Friday, July 29, 2011

Whatever happened to programming? (link)

I want to make things, not just glue things together. When people ask me what I like about my job, I always say the same thing: that its the thrill of starting with nothing and making something. That, for me, is the essence of programming, and it hurts that there isn’t as much of it about as there used to be.

Read a full article here...

Oracle released Java 7 today with hotspot compiler optimizations, which miscompile some loops

Oracle released Java 7 today. Unfortunately it contains hotspot compiler
optimizations, which miscompile some loops. This can affect code of several
Apache projects. Sometimes JVMs only crash, but in several cases, results
calculated can be incorrect, leading to bugs in applications (see Hotspot
bugs 7070134 [1], 7044738 [2], 7068051 [3]).

Read more...

The Secret Ingredient In Your Orange Juice (link)

Read here...

Thursday, July 28, 2011

GeoCoding with C# and Google Geocoding API V3 (using JSON this time)

In previous article I have shown how to use Google Geocoding API V3 from C#. We were using XML output format in that example. Now we will use JSON output format. For JSON parsing I will use Json.NET library.

Ok here is the code GeoCoding with C# and Google Geocoding API V3 using JSON output format:
using System;
using System.IO;
using System.Net;
using Newtonsoft.Json;

namespace GeoCoderJson
{
    class Program
    {
        public class GeoLocation
        {
            public decimal Lat { get; set; }
            public decimal Lng { get; set; }
        }

        public class GeoGeometry
        {
            public GeoLocation Location { get; set; }
        }

        public class GeoResult
        {
            public GeoGeometry Geometry { get; set; }
        }

        public class GeoResponse
        {
            public string Status { get; set; }
            public GeoResult[] Results { get; set; }
        }

        static void Main (string[] args)
        {
            string url = "http://maps.googleapis.com/maps/api/geocode/" +
                "json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=false";

            WebResponse response = null;
            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create (url);
                request.Method = "GET";
                response = request.GetResponse ();
                if (response != null)
                {
                    string str = null;
                    using (Stream stream = response.GetResponseStream())
                    {
                        using (StreamReader streamReader = new StreamReader(stream))
                        {
                            str = streamReader.ReadToEnd ();
                        }
                    }

                    GeoResponse geoResponse = JsonConvert.DeserializeObject<GeoResponse>(str);
                    if (geoResponse.Status == "OK")
                    {
                        int count = geoResponse.Results.Length;
                        for (int i = 0; i < count; i++)
                        {
                            Console.WriteLine ("Lat: {0}", geoResponse.Results [i].Geometry.Location.Lat);
                            Console.WriteLine ("Lng: {0}", geoResponse.Results [i].Geometry.Location.Lng);
                        }
                    } 
                    else
                    {
                        Console.WriteLine ("JSON response failed, status is '{0}'", geoResponse.Status);
                    }
                }
            } 
            catch (Exception ex)
            {
                Console.WriteLine (ex.Message);
            } 
            finally
            {
                Console.WriteLine ("Clean up");
                if (response != null)
                {
                    response.Close ();
                    response = null;
                }
            }

            Console.WriteLine ("Done.");
            Console.ReadLine ();
        }
    }
}

And here is the output:
Lat: 37.4217420
Lng: -122.08416580
Clean up
Done.

Wednesday, July 27, 2011

Steve Yegge let's solve real problems!

Steve Yegge quits Google in the middle of his speech [OSCON Data 2011]video is here. He encourages all hacker to learn some math, statistics and bioinformatics for good. Let's stop making social crap like Facebook (include clones). Let's help solve some long standing hard problem like this one!

Running log 2011-07-27

Just finished 1 lap ~2km... My mind is clear again :)

Ten Ways to Check if an Integer Is a Power Of Two in C (link)

read here...

How to get started with functional programming (link)

A good advice read here...

Tuesday, July 26, 2011

The Higgs Boson - A one page explanation! (link)

a fine reading for coffee break...

Five Popular Web Strategies That Don't Work (link)

Very good summary...

Stand-alone code for numerical computing (link)

Go here...

FTPS also known as FTP over SSL example with C++ and libCURL


In this post I showed how to use C# and libcurl.NET to connect to FTPS. Now I will use C++ so you could compare both implementations.

Read the following Wikipedia article for background about FTPS.

And here follows the code...
#include <string>
#include <iostream>
#include "CURLWrapper.h"

using std::cout;
using std::endl;
using std::string;

static string buffer;

static int writer(char *data, size_t size, size_t nmemb, string *buffer)
{
    int result = 0;
    if (buffer != NULL)
    {
        buffer->append(data, size * nmemb);
        result = size * nmemb;
    }

    return result;
}

int main()
{
    string url = "ftp://user:thepassword@ftp.somesite.com/dir/";

    cout << "Will retrive from url: '" << url << "'" << endl;

    CURLcode code = CURLWrapper::GlobalInit(CURL_GLOBAL_ALL);
    if (code != CURLE_OK)
    {
        cout << "CURL init failed" << endl;
        return 0;
    }

    CURLWrapper::Easy easy;
    easy.SetOption(CURLOPT_URL, url.c_str());
    easy.SetOption(CURLOPT_SSL_VERIFYPEER, 0);
    easy.SetOption(CURLOPT_SSL_VERIFYHOST, 0);
    easy.SetOption(CURLOPT_FTP_SSL, CURLFTPSSL_TRY);

    easy.SetOption(CURLOPT_FTPLISTONLY, 1);

    easy.SetOption(CURLOPT_WRITEFUNCTION, writer);
    easy.SetOption(CURLOPT_WRITEDATA, &buffer);
    easy.Perform();

    if (easy.IsOK())
    {
        cout << "CURL: response is OK " << endl;
 
        if (!buffer.empty())
        {
            cout << buffer << endl;
        }
        else
        {
            cout << "CURL: respose is empty! " << endl;
        }
    }
    else
    {
        cout << "CURL Error: [ " << easy.GetError() <<  ] - " 
            << easy.GetErrorMessage() << endl;
    }

    CURLWrapper::GlobalCleanup();
}

And here is code for CURLWrapper class (I have added GlobalInit and GlobalCleanup procedures from the previous libCURL post here)...

"CURLWrapper.h"
#ifndef CURL_WRAPPER_H
#define CURL_WRAPPER_H

#include <string>
#include "curl/curl.h"

namespace CURLWrapper 
{
    CURLcode GlobalInit(int flags);
    void GlobalCleanup();
    
    class Easy
    {
    public:
        Easy();
        ~Easy();

        void Init();
        void Cleanup();
        void Reset();

        template <typename T, typename V>
        void SetOption(T option, V parameter)
        {
            curl_easy_setopt(mCurl, option, parameter);
        }

        void Perform();
        bool IsOK();
        CURLcode GetError();
        std::string GetErrorMessage();
    
    private:
        void ErrorBuffer(char* buffer); 
    
    private:
        CURL* mCurl;
        char mErrorBuffer[CURL_ERROR_SIZE + 1];
        CURLcode mCode;
    };
}
#endif //#ifndef CURL_WRAPPER_H

"CURLWrapper.cpp"
#include <memory>
#include <algorithm>
#include "CURLWrapper.h"
#include "curl/curl.h"

CURLcode CURLWrapper::GlobalInit(int flags)
{
    return curl_global_init(flags);
}

void CURLWrapper::GlobalCleanup()
{
    curl_global_cleanup();
}

CURLWrapper::Easy::Easy()
    : mCurl(curl_easy_init()),
    mCode(CURLE_OK)
{
}

CURLWrapper::Easy::~Easy()
{
    curl_easy_cleanup(mCurl);
}

void CURLWrapper::Easy::Init()
{
}

void CURLWrapper::Easy::Cleanup()
{
    curl_easy_cleanup(mCurl);
}

void CURLWrapper::Easy::Reset()
{
    curl_easy_reset(mCurl);
    std::fill(mErrorBuffer, mErrorBuffer + CURL_ERROR_SIZE + 1, 0);
    ErrorBuffer(mErrorBuffer);
    mCode = CURLE_OK;
}

void CURLWrapper::Easy::ErrorBuffer(char* buffer)
{
    SetOption(CURLOPT_ERRORBUFFER, (void*)buffer);
}

void CURLWrapper::Easy::Perform()
{
    mCode = curl_easy_perform(mCurl);
}

bool CURLWrapper::Easy::IsOK()
{
    return mCode == CURLE_OK;
}

CURLcode CURLWrapper::Easy::GetError()
{
    return mCode;
}

std::string CURLWrapper::Easy::GetErrorMessage()
{
    return std::string(mErrorBuffer);
}

And as always the magic command:
g++ -g -Wall -o prog prog.cpp CURLWrapper.cpp -lcurl


So this is it, I hope that this post will help you to discover this wonderful libCURL library ;)

Monday, July 25, 2011

Smart pointers in Boost, TR1, and C++x0 (link)

This post is an overview of the smart pointers available in Boost, TR1, and C++x0. It also touches on the availability and portability of the last two options when it comes to various C++ compilers. Read full article here...

Sunday, July 24, 2011

Get there slower and enjoy the ride!

The Acceleration of Addictiveness (link)

I used to think running was a better form of exercise than hiking because it took less time. Now the slowness of hiking seems an advantage, because the longer I spend on the trail, the longer I have to think without interruption.

- Paul Graham (The Acceleration of Addictiveness)

Friday, July 22, 2011

C# IDbConnection && IDbCommand && IDataReader: where is my abstraction?

Way every ado.net example I spot on internet is still coded against concrete implementation of Connection && Command && DataReader instead of Interfaces?

It is so simple to use provider factory here follows a code example:
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Data;

namespace Utils
{
  public static class DBUtils
  {
    public static IList ExecuteQuery(string query, string connectionString, string providerName)
    {
      if (string.IsNullOrEmpty(query))
        throw new ArgumentNullException("Query text is null or empty!");

      if (string.IsNullOrEmpty(connectionString))
        throw new ArgumentNullException("ConnectionString is null or empty!");

      if (string.IsNullOrEmpty(providerName))
        throw new ArgumentNullException("ProviderName is null or empty!");

      IList results = null;

      DbProviderFactory providerFactory = DbProviderFactories.GetFactory(providerName);
      if (providerFactory == null)
        throw new Exception("Failed to get DbProviderFactory instnce!");

      using (IDbConnection con = providerFactory.CreateConnection())
      {
        con.ConnectionString = connectionString;

        if (con.State != ConnectionState.Open)
          con.Open();

        using (IDbCommand cmd = providerFactory.CreateCommand())
        {
          cmd.CommandText = query;
          cmd.Connection = con;

          using (IDataReader reader = cmd.ExecuteReader())
          {
            results = new List();
            while (reader.Read())
            {
              object[] values = new object[reader.FieldCount];
              int count = reader.GetValues(values);
              results.Add(values);
              values = null;
            }
          }
        }
      }

      return results;
    }
  }
}

NHibernate FAQ: is bathcing supported in MSSQL only?

ado_batchsize is using a feature of ADO.Net which allows to send multiple commands without waiting for the first response to come back. The actual DB shouldn't be aware of that whatsoever.

Why I Hate Frameworks (link)

A very funny analogy about Frameworks. Go read here...

Thursday, July 21, 2011

A bit of linux: recursive creation of directorie

Here follows example:
mkdir -p cpp/google_code_jam/EuroPython2011/A

Wednesday, July 20, 2011

A bit of C++0x Support in GCC

Here is a good link if you want to check what C++0x features are supported in specific GCC version.

A bit of C++ The typeid operator

In C++ typeid operator is used to determine actual derived type of an object at run time. This operator is provided for runtime type identification (RTTI) support in C++.

Here follows an example of typeid operator in action:
#include <typeinfo>
#include <iostream>
#include <string>
#include <vector>

using std::cout;
using std::endl;
using std::string;
using std::vector;

int main()
{
    string v1 = "";
    cout << "v1: " << typeid(v1).name() << endl;
    vector<int> v2();
    cout << "v2: " << typeid(v2).name() << endl;

    return 0;
}

results:
v1: Ss
v2: FSt6vectorIiSaIiEEvE

std::type_info::name() returns an implementation specific name. As you can see GCC just gives you the internal, mangled name.

In GCC you can use abi::__cxa_demangle() to get nice name.

Here is example
#include <typeinfo>
#include <iostream>
#include <vector>
#include <cxxabi.h>

using std::cout;
using std::endl;
using std::vector;

int main()
{
    vector<int> v2();

    int success;
    char *realname = abi::__cxa_demangle(typeid(v2).name(), 0, 0, &success);
    cout << "v2: " << typeid(v2).name() 
        << " nice name: " << realname << endl;
    free(realname);

    return 0;
}

Results:
v2: FSt6vectorIiSaIiEEvE nice name: std::vector<int, std::allocator<int> > ()()

C++ capitalize each word in string

(Go here for C# implementation)

So here it is: source code for capitalizing first letter of each word in string
#include <iostream>
#include <string>
#include <algorithm>
#include <locale>

using std::string;
using std::locale;
using std::endl;
using std::cout;

int main()
{
    locale loc;

    string text = "How to capitalize the first character of each word?"
        " Other characters should be lower case.";

    cout << text << endl;

    int count = text.size();
    if (count > 0)   
    {
        text[0] = toupper(text[0], loc);
    }

    for(int i = 1; i < count; i++)
    {
        if (isspace(text[i - 1], loc))
            text[i] = toupper(text[i], loc);
        else
            text[i] = tolower(text[i]);
    }

    cout << text << endl;

    return 0;
}

Tuesday, July 19, 2011

Linux 3.0 not ready for today or why do we always find the subtle bugs just before a release?


Read more here...

ILSpy 1.0 Has Landed

ILSpy is the open-source .NET assembly browser and decompiler.

Features
  • Assembly browsing
  • IL Disassembly
  • Decompilation to C# (Supports lambdas and 'yield return', shows XML documentation)
  • Saving of resources
  • Search for types/methods/properties (substring)
  • Hyperlink-based type/method/property navigation
  • Base/Derived types navigation
  • Navigation history
  • BAML to XAML decompiler
  • Save Assembly as C# Project
  • Find usage of field/method
  • Extensible via plugins (MEF)

Monday, July 18, 2011

Google: The Beginning

Read here...

VirtualBox 4.0.12 released!


This is a maintenance release. The following items were fixed and/or added:
  • Mac OS X hosts: Lion fixes
  • Solaris hosts: fixed preemption issue with Solaris 11 hosts (builds 166 and above)
  • VBoxManage: more convenient configuration of storage controller attachments by automatically determining the port or device parameter when a storage controller has only one port or device per port (bug #9188)
  • Storage: fixed possible data corruption under certain circumstances whith VHD and Parallels images (bug #9150)
  • Storage: fixed access to CD/DVD images beyond 4GB when using the SATA controller (bug #8592)
  • Floppy: make it possible to unmount a host floppy disk (bug #6651)
  • Networking: fixed the problem with segmentation offloading when several VMs were transmitting at once
  • 3D support: fixed GL_VERSION string for different locales (bug #8916)
  • Sources: fixed USB 2.0 support using extension packs for non-official builds
  • Solaris Additions: fixed automounting of shared folders (bug #8014)

Maybe C++ hasn’t jumped the shark after all (link)

The new standard is out now, and I find it more interesting that I thought I would have. I’d still rather not use C++ for tasks that are easier in another language I know, but sometimes I don’t have that option.

Read here...

Sunday, July 17, 2011

Debian GNU/Hurd by end of 2012? (link)

According to the most recent progress report from the project, there is now a "real plan" to release a Hurd variant of Debian with the release of Debian 7.0 Wheezy.

Read more here...

Saturday, July 16, 2011

Passion has a funny way of trumping logic

The theory of evolution claims only the strong shall survive. Maybe so, maybe so. But the theory of competition says just because they're the strong, doesn't mean they can't get their asses kicked.

PuTTY version 0.61 is released

Official home site and detailed change log for 0.61 version

Friday, July 15, 2011

BTRFS: The Good, The Bad and The Ugly (link)

Read about BTRFS and performance problems

Libraries vs Frameworks (link)

The word to focus on here is change. As your app grows, you will have to change your mind about what is a good idea, and what doesn't work for you. The first solution that you come up with for a problem is almost never good enough. Limiting your choice to the confines of a framework means limiting your choice in how you can solve a problem. Limiting your choice very often ends up being a bad thing for the software.
read more...

There is no quick way to learn programming (link)

There is no quick way to learn programming - no tool will help.

Your brain is a zillion times better than the best IDE. programs
form in you brain not in an IDE.
...

Have fun - if it's not fun it is pointless - don't fight the tools
all you need is a text editor and the erlang shell to start with.

- Joe Armstrong

Read all text here...

Thursday, July 14, 2011

FTPS also known as FTP over SSL example with C# and libCURL (libcurl.NET)


Background

Two separate methods were developed to invoke client security for use with FTP clients: Explicit or Implicit. The explicit method is a legacy compatible implementation where FTPS aware clients can invoke security with an FTPS aware server without breaking overall FTP functionality with non-FTPS aware clients. The implicit method requires that all clients of the FTPS server be aware that SSL is to be used on the session, and thus is incompatible with non-FTPS-aware clients.

- Wikipedia (link to Wikipedia FTPS article)

Download libcurl.NET

Go to libcurl.NET home page and download library (link to file download).

Create and setup new solution

Your solution should look like this:


Extract and copy libcurl.NET files to your solution libs directory should get something like this:


Add LibCurlNet refernce from libcurl.NET files bin directory to your project.

Copy libcurl.dll, LibCurlShim.dll and ca-bundle.crt files from libcurl.NET files bin directory to your project root directory. Add libcurl.dll, LibCurlShim.dll and ca-bundle.crt files to project tree and set their properties to 'Copy if newer' value.

Add the following source code to your Program.cs file Main method:

Source code

using System;
using System.Collections.Generic;
using SeasideResearch.LibCurlNet;

namespace libcurlFtpsExample
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("libcurlFtpsExample...");

            const string url = "ftp://user:thepassword@ftp.somesite.com/dir/";

            try
            {
                Curl.GlobalInit((int)CURLinitFlag.CURL_GLOBAL_ALL);

                Easy easy = new Easy();
                if (easy != null)
                {
                    easy.SetOpt(CURLoption.CURLOPT_URL, url);
                    easy.SetOpt(CURLoption.CURLOPT_SSL_VERIFYPEER, false);
                    easy.SetOpt(CURLoption.CURLOPT_SSL_VERIFYHOST, false);
                    easy.SetOpt(CURLoption.CURLOPT_FTP_SSL, CURLftpSSL.CURLFTPSSL_TRY);

                    // For debugging will print headers to console.
                    Easy.HeaderFunction hf = new Easy.HeaderFunction(OnHeaderData);
                    easy.SetOpt(CURLoption.CURLOPT_HEADERFUNCTION, hf);
                    
                    // For debugging will print received data to console.
                    Easy.DebugFunction df = new Easy.DebugFunction(OnDebug);
                    easy.SetOpt(CURLoption.CURLOPT_DEBUGFUNCTION, df);
                    easy.SetOpt(CURLoption.CURLOPT_VERBOSE, true);
     
                    // List directory only
                    easy.SetOpt(CURLoption.CURLOPT_FTPLISTONLY, true);
         
                    CURLcode code = easy.Perform();
                    if (code != CURLcode.CURLE_OK)
                    {
                        Console.WriteLine("Request failed!");
                    }

                    easy.Cleanup();
                }
                else
                {
                    Console.WriteLine("Failed to get Easy libcurl handle!");
                }
            }
            catch (Exception exp)
            {
                Console.WriteLine(exp);
            }
            finally
            {
                Curl.GlobalCleanup();
            }
        }

        public static void OnDebug(CURLINFOTYPE infoType, String msg, Object extraData)
        {
            // print out received data only
            if (infoType == CURLINFOTYPE.CURLINFO_DATA_IN)
                Console.WriteLine(msg);
        }

        public static Int32 OnHeaderData(Byte[] buf, Int32 size, Int32 nmemb, Object extraData)
        {
            Console.Write(System.Text.Encoding.UTF8.GetString(buf));
                return size * nmemb;
        }
    }
}


And here is output from program:


Excercise
What about file download instead of directory listing?

Well comment out line no. 37

easy.SetOpt(CURLoption.CURLOPT_FTPLISTONLY, true);

and replace it with this code:

Easy.WriteFunction wf = new Easy.WriteFunction(OnWriteData);
easy.SetOpt(CURLoption.CURLOPT_WRITEFUNCTION, wf);

and add implementation of OnWriteData static method in 'Program' class like this:

// only prints file context to console
public static Int32 OnWriteData(Byte[] buf, Int32 size, Int32 nmemb, Object extraData)
{
    Console.Write(System.Text.Encoding.UTF8.GetString(buf));
    return size * nmemb;
}

Also add your file at the end of url like this:

const string url = "ftp://user:thepassword@ftp.somesite.com/dir/yourfile.txt";

Done ;)

Wednesday, July 13, 2011

Tuesday, July 12, 2011

Firefox 8 is 20% faster than Firefox 5, matches Chrome 14 (link)

read here...

Quote of The Day - 2011-07-12

There’s a subtle reason that programmers always want to throw away the code and start over. The reason is that they think the old code is a mess. … The reason that they think the old code is a mess is because of a cardinal, fundamental law of programming: It’s harder to read code than to write it.

- Joel Spolsky

Go Rocks - How Can We Avoid Something This Bad In The Future? (link)

An explanation for the ambivalent reactions to the Go language

Saturday, July 9, 2011

Quote of The Day - 2011-07-09

The formulation of a problem is often more essential than its solution, which may be merely a matter of mathematical or experimental skill.

- Albert Einstein

Friday, July 8, 2011

Quote of The Day - 2011-07-08

The basic need, which certainly is obvious only in man, is the need of symbolization. The symbol-making function is one of man’s primary activities, like eating, looking, or moving about. It is the fundamental process of his mind, and goes on all the time.

- Susanne K. Langer

Thursday, July 7, 2011

GeoCoding with C++ and Google Geocoding API V3 (using libCURL and JsonCpp)

Geocoding is the process of finding associated geographic coordinates (often expressed as latitude and longitude) from other geographic data, such as street addresses, or zip codes (postal codes). (read more in wikipedia)

Today I'll give a short example of C++ application in which we will use the newest version of Google Geocoding API V3. You can compare it with similar C# geocoding example.

When you perform a geocoder request, you can specify which output type to use. The available options are JSON, XML, KML and CSV. We will be requesting and handling JSON data.

For example, if you wanted to find the coordinates of house located at 1600 Amphitheatre Parkway, Mountain View, CA, you would request the following URL: (http://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=false).

We will use cURL libcurl library for requests.

The response will be processed by using JsonCpp library and coordinates will be printed to console.

OK, here is the code of my geocoder example:
#include <string>
#include <iostream>
#include "json/json.h"
#include "CURLWrapper.h"

static std::string buffer;

static int writer(char *data, size_t size, size_t nmemb, std::string *buffer)
{
    int result = 0;
    if (buffer != NULL)
    {
        buffer->append(data, size * nmemb);
        result = size * nmemb;
    }

    return result;
}

int main()
{
    std::string url = "http://maps.googleapis.com/maps/api/geocode/json?"
   "address=1600+Amphitheatre+Parkway,+Mountain+View,"
   "+CA&sensor=false";

    std::cout << "Will retrive from url: '" << url << "'" << std::endl;

    CURLWrapper::Easy easy;
    easy.SetOption(CURLOPT_URL, url.c_str());
    easy.SetOption(CURLOPT_HEADER, 0);
    easy.SetOption(CURLOPT_FOLLOWLOCATION, 1);
    easy.SetOption(CURLOPT_WRITEFUNCTION, writer);
    easy.SetOption(CURLOPT_WRITEDATA, &buffer);
    easy.Perform();

    if (easy.IsOK())
    {
        std::cout << "CURL: response is OK " << std::endl;
        //std::cout << buffer << std::endl;
 
        if (!buffer.empty())
        {
            Json::Value root;
            Json::Reader reader;
     
            if (reader.parse(buffer, root))
            {
                std::cout << "JSON response is OK!" << std::endl;
  
                const Json::Value status = root["status"];
                std::cout << "JSON response status: '" 
                    << status.asString() << "'" 
                    << std::endl;

                if (status.asString() == "OK")
                {
                    const Json::Value results = root["results"];
      
                    std::cout << "JSON response results.size = " 
                        << results.size() << std::endl;

                    for(unsigned int i = 0; i < results.size(); i++)
                    {
                        const Json::Value geometry = results[i]["geometry"];
   
                        std::cout << "Coordinates: " 
                            << "lat=" << geometry["location"]["lat"].asString()
                            << " "
                            << "lng=" << geometry["location"]["lng"].asString()
                            << std::endl;
                    }
                }
                else
                {
                    std::cout << "JSON response contains no results" 
                        << std::endl;
                }
            }
            else
            {
                std::cout << "JSON response Error: "  
                    << reader.getFormattedErrorMessages() 
                    << std::endl;
            }
        }
        else
        {
            std::cout << "CURL: respose is empty! " << std::endl;
        }
    }
    else
    {
        std::cout << "CURL Error: [ " << easy.GetError() << " ] - " 
            << easy.GetErrorMessage() << std::endl;
    }
}


In order to compile this example you would also need my libcurl wrapper class: CURLWrapper (which is heavily inspired by cURLpp project). Here is the code for it:
"CURLWrapper.h" file
#ifndef CURL_WRAPPER_H
#define CURL_WRAPPER_H

#include <string>
#include "curl/curl.h"

namespace CURLWrapper 
{
    class Easy
    {
    public:
        Easy();
        ~Easy();

        void Init();
        void Cleanup();
        void Reset();

        template <typename T, typename V>
        void SetOption(T option, V parameter)
        {
            curl_easy_setopt(mCurl, option, parameter);
        }

        void Perform();
        bool IsOK();
        CURLcode GetError();
        std::string GetErrorMessage();
    
    private:
        void ErrorBuffer(char* buffer); 
    
    private:
        CURL* mCurl;
        char mErrorBuffer[CURL_ERROR_SIZE + 1];
        CURLcode mCode;
    };

}

#endif //#ifndef CURL_WRAPPER_H


"CURLWrapper.cpp" file
#include <memory>
#include <algorithm>
#include "CURLWrapper.h"
#include "curl/curl.h"

CURLWrapper::Easy::Easy()
    : mCurl(curl_easy_init()),
    mCode(CURLE_OK)
{
}

CURLWrapper::Easy::~Easy()
{
    curl_easy_cleanup(mCurl);
}

void CURLWrapper::Easy::Init()
{
}

void CURLWrapper::Easy::Cleanup()
{
    curl_easy_cleanup(mCurl);
}

void CURLWrapper::Easy::Reset()
{
    curl_easy_reset(mCurl);
    std::fill(mErrorBuffer, mErrorBuffer + CURL_ERROR_SIZE + 1, 0);
    ErrorBuffer(mErrorBuffer);
    mCode = CURLE_OK;
}

void CURLWrapper::Easy::ErrorBuffer(char* buffer)
{
    SetOption(CURLOPT_ERRORBUFFER, (void*)buffer);
}

void CURLWrapper::Easy::Perform()
{
    mCode = curl_easy_perform(mCurl);
}

bool CURLWrapper::Easy::IsOK()
{
    return mCode == CURLE_OK;
}

CURLcode CURLWrapper::Easy::GetError()
{
    return mCode;
}

std::string CURLWrapper::Easy::GetErrorMessage()
{
    return std::string(mErrorBuffer);
}


You can compile example like this:
g++ -g -Wall -Ilibs/include -Llibs/lib -o prog prog.cpp CURLWrapper.cpp -lcurl -ljson_linux-gcc-4.5.2_libmt

And here is result screenshot:

Quote of The Day - 2011-07-07

Man can be destroyed, but not defeated.

- Ernest Hemingway

Tuesday, July 5, 2011