Monthly Archives: November 2008

convert hex string to int values in C++

boost::lexical_cast is quite handy to convert between string and numerical types. However, sometimes you need more. for example, when you want to convert a string "0x0A" to its int value 0x0A(10), or vice versa. you are out of luck. The following code comes handy for this purpose.

#pragma once
#include <string>
#include <sstream>
#include <iomanip>

// the following routines convert dec/hex string literal to size_t values

namespace numeric_conversion
{
    template <typename T, bool is_hex>
    size_t string_to_size_t(const std::basic_string<T>& s)
    {
        std::basic_istringstream<T> ss(s, std::ios_base::in);

        size_t size(0);
        ss >> (is_hex ? std::hex : std::dec )>>size;
        return size;
    }

    template <typename T>
    size_t hexstring_to_size_t(const std::basic_string<T>& s)
    {
        return string_to_size_t<T, true>(s);
    }

    template <typename T>
    size_t hexstring_to_size_t(const T* s)
    {
        return string_to_size_t<T, true>(std::basic_string<T>(s));
    }

    template <typename T>
    size_t decstring_to_size_t(const std::basic_string<T>& s)
    {
        return string_to_size_t<T, false>(s);
    }

    template <typename T>
    size_t decstring_to_size_t(const T* s)
    {
        return string_to_size_t<T, false>(std::basic_string<T>(s));

    }

    template <int N>
    std::wstring to_hex_string(size_t i, bool map_0_to_empty)
    {
        if(map_0_to_empty && (0 == i)) return L"";

        std::wstringstream wss;
        wss << L"0x"/*std::showbase*/ << std::hex << std::setw(N) << std::setfill(L'0') << i;

        return wss.str();
    }

}
Test code:
#include <iostream>
int main()
{
	using namespace std;
	using namespace numeric_conversion;
	
	wcout << L"convert string with base: 0x0a = " << hexstring_to_size_t(L"0x0a") << endl;
	wcout << L"convert string with base no base: 0a = " << hexstring_to_size_t(L"0a") << endl;	
	wcout << L"convert value to hex string: 0a = " << to_hex_string<2>(10, true);

}
Output:
image 

Advertisements

Duplicate File Finder

I am in need of a tool to find the duplicate files on my computer. I would have write one myself with boost.filesystem, but I searched online first and found this free code.  By tweaking a little with this code. I added the delete feature.

image

Binary can be downloaded from here.

Boost.Thread, Condition Variables &Spurious wakeup

 boost::condition_variable is a utility to synchronize threads, and can be used as below:

boost::condition_variable cond;
boost::mutex mut;
bool data_ready;

void process_data();

void wait_for_data_to_process()
{
    boost::unique_lock<boost::mutex> lock(mut);
    while(!data_ready)
    {
        cond.wait(lock);
    }
    process_data();
}

This example is simple and intuitive except for one thing, according to this documentation,

 void wait(boost::unique_lock<boost::mutex>& lock)

Effects:


Atomically call lock.unlock() and blocks the current thread.

The thread will unblock when notified by a call to this->notify_one()

or this->notify_all(), or spuriously.

When the thread is unblocked (for whatever reason),

the lock is reacquired by invoking lock.lock() before the call to wait returns.

The lock is also reacquired by invoking lock.lock()

if the function exits with an exception.

Since  Wait() blocks the thread, why in the above example code snippet

while(!data_ready)

rather than

if(!data_ready)

is used?

This is because a spurious wakeup may cause cond.wait(lock) to return while data_ready remains unchanged(false).

This post gives a very detailed discussion about this issue.