<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Kier&#039;s Blog &#187; Twitter</title>
	<atom:link href="http://www.kierdugan.com/tag/twitter/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kierdugan.com</link>
	<description>Damn right.</description>
	<lastBuildDate>Fri, 11 Mar 2011 23:36:36 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Twitter Me Xerces!</title>
		<link>http://www.kierdugan.com/2010/03/25/twitter-me-xerces/</link>
		<comments>http://www.kierdugan.com/2010/03/25/twitter-me-xerces/#comments</comments>
		<pubDate>Thu, 25 Mar 2010 00:03:42 +0000</pubDate>
		<dc:creator>Kier</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Random]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[libcurl]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Twitter]]></category>
		<category><![CDATA[Xerces]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://www.kierdugan.com/?p=58</guid>
		<description><![CDATA[Following from the spirit of yesterdays post, little victories&#8230;
Yesterday I managed to download the front page of my website using<a href="http://www.kierdugan.com/2010/03/25/twitter-me-xerces/" class="searchmore">Read the Rest...</a><div class="clr"></div>]]></description>
			<content:encoded><![CDATA[<p>Following from the spirit of yesterdays post, little victories&#8230;</p>
<p>Yesterday I managed to download the front page of my website using <a href="http://curl.haxx.se/libcurl/" target="_blank">libcurl</a>. As good as that was as a learning experience, it wasn&#8217;t interesting or useful in the slightest. Today however, I decided to see if I could fetch my status updates from Twitter and display them in a program. So I had a look at the API documentation and it looks quite easy to use, with the exception of OAuth which I&#8217;m yet to get my head around. Thankfully, for now, basic authentication is still supported.</p>
<p>The Twitter API uses the REST (REpresentational State Transfer) paradigm which means there&#8217;s no concept of a <em>state</em> on the server; i.e. each transaction is considered separately. It also means that it uses HTTP, which is pretty simple to understand. Basically in a REST protocol the URI&#8217;s are objects in the system, and the HTTP verbs are how you interact with them. So a GET on a <span style="font-family: Courier New;">http://server/article?name=REST</span> object would download an <em>article</em> named <em>REST</em>. Simple eh? Check <a href="http://www.codeproject.com/KB/architecture/RESTWebServicesPart2.aspx" target="_blank">this article</a> if you&#8217;re interested.</p>
<p>Anyway, onto the meat &#8216;n&#8217; taters. Data in a REST transaction is typically stored as XML or JSON. I considered downloading <a href="http://pyyaml.org/wiki/LibYAML" target="_blank">LibYAML</a> and taking the JSON route but a) I already had <a href="http://xerces.apache.org/xerces-c" target="_blank">Xerces</a>, b) I understand XML more than JSON, and c) I couldn&#8217;t be bothered to learn yet another new thing.</p>
<p><span id="more-58"></span>Xerces is incredibly well written. If you look at the class listings of Xerces or <a href="http://xml.apache.org/xalan-c/" target="_blank">Xalan</a> you&#8217;ll appreciate they&#8217;re both <strong>enormous</strong> and support basically everything. In fact, right out of the box Xerces supports fetching XML documents over the internet using HTTP GET. I chose not to use this purely because I wanted to use libcurl. Thankfully libcurl is surprisingly easy to use:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">static</span> <span style="color: #0000ff;">size_t</span> _CurlWriteCB <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #000040;">*</span> ptr, <span style="color: #0000ff;">size_t</span> nLen, <span style="color: #0000ff;">size_t</span> cbElem,
                            CMemFile<span style="color: #000040;">*</span> pFile<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">size_t</span> cbSizeAtStart<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">size_t</span> cbSizeAtEnd<span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #666666;">// Write data to file, but measure buffer size before and after.</span>
    cbSizeAtStart <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">size_t</span><span style="color: #008000;">&#41;</span>pFile<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>GetLength <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    pFile<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>Write <span style="color: #008000;">&#40;</span>ptr, <span style="color: #008000;">&#40;</span>UINT<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span>nLen <span style="color: #000040;">*</span> cbElem<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    cbSizeAtEnd   <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">size_t</span><span style="color: #008000;">&#41;</span>pFile<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>GetLength <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #666666;">// Return the difference in buffer size, i.e. number of bytes written.</span>
    <span style="color: #0000ff;">return</span> <span style="color: #008000;">&#40;</span>cbSizeAtEnd <span style="color: #000040;">-</span> cbSizeAtStart<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
BYTE<span style="color: #000040;">*</span> GetStatusesFromTwitter <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">char</span><span style="color: #000040;">*</span> szUserName, UINT<span style="color: #000040;">&amp;</span> uiSize<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #666666;">// Attempt to initialise curl</span>
    CURL<span style="color: #000040;">*</span> curl <span style="color: #000080;">=</span> curl_easy_init <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>curl <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        <span style="color: #666666;">// Set up the http target</span>
        CString strFmt<span style="color: #008080;">;</span>
        strFmt.<span style="color: #007788;">Format</span> <span style="color: #008000;">&#40;</span>IDS_TWITTER_STATUS, szUserName<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        curl_easy_setopt <span style="color: #008000;">&#40;</span>curl, CURLOPT_URL, strFmt.<span style="color: #007788;">GetString</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
        <span style="color: #666666;">// Save the result into memory for now.</span>
        CMemFile buffer<span style="color: #008080;">;</span>
        curl_easy_setopt <span style="color: #008000;">&#40;</span>curl, CURLOPT_WRITEFUNCTION, _CurlWriteCB<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        curl_easy_setopt <span style="color: #008000;">&#40;</span>curl, CURLOPT_WRITEDATA,     <span style="color: #000040;">&amp;</span>buffer<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
        <span style="color: #666666;">// Attempt to grab the data from Twitter.</span>
        CURLcode res <span style="color: #000080;">=</span> curl_easy_perform <span style="color: #008000;">&#40;</span>curl<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        curl_easy_cleanup <span style="color: #008000;">&#40;</span>curl<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
        <span style="color: #666666;">// Return the data.</span>
        <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>res <span style="color: #000080;">==</span> <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
            uiSize <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>UINT<span style="color: #008000;">&#41;</span>buffer.<span style="color: #007788;">GetLength</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
            <span style="color: #0000ff;">return</span> buffer.<span style="color: #007788;">Detach</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>The above listing will download a users tweets and store them in a growable buffer (see <a href="http://msdn.microsoft.com/en-us/library/tzdxd4x0.aspx" target="_blank">CMemFile</a>). But now we have to present this to Xerces in a way that it will understand. Thankfully we can supply an arbitrary <a href="http://xerces.apache.org/xerces-c/apiDocs-2/classInputSource.html" target="_blank">InputSource</a> to a <a href="http://xerces.apache.org/xerces-c/apiDocs-2/classXercesDOMParser.html" target="_blank">DOMParser</a>, including one that will <a href="http://xerces.apache.org/xerces-c/apiDocs-2/classMemBufInputSource.html" target="_blank">wrap a piece of memory</a>.</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">bool</span> DoGetStatuses <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">char</span><span style="color: #000040;">*</span> szUserName<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #666666;">// Query Twitter</span>
    UINT  uiSize<span style="color: #008080;">;</span>
    BYTE<span style="color: #000040;">*</span> pbData <span style="color: #000080;">=</span> GetStatusesFromTwitter <span style="color: #008000;">&#40;</span>szUserName, uiSize<span style="color: #008000;">&#41;</span>
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>pbData <span style="color: #000080;">==</span> <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span>
        <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #666666;">// Move the memory into an object Xerces understands.</span>
    MemBufInputSource<span style="color: #000040;">*</span> pDataSrc <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> MemBufInputSource
        <span style="color: #008000;">&#40;</span>pbData, uiSize, L<span style="color: #FF0000;">&quot;TwitterXML&quot;</span>, <span style="color: #0000ff;">true</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #666666;">// Parse the data</span>
    XercesDOMParser parser<span style="color: #008080;">;</span>
    parser.<span style="color: #007788;">setValidationScheme</span> <span style="color: #008000;">&#40;</span>XercesDOMParser<span style="color: #008080;">::</span><span style="color: #007788;">Val_Never</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    parser.<span style="color: #007788;">setDoNamespaces</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">false</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    parser.<span style="color: #007788;">setDoSchema</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">false</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    parser.<span style="color: #007788;">setDoValidation</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">false</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    parser.<span style="color: #007788;">parse</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span><span style="color: #008000;">&#40;</span>InputSource<span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>pDataSrc<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #666666;">// Get the root node</span>
    DOMDocument<span style="color: #000040;">*</span> pDoc <span style="color: #000080;">=</span> parser.<span style="color: #007788;">getDocument</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #666666;">//...</span>
&nbsp;
    <span style="color: #666666;">// Free memory.</span>
    <span style="color: #0000dd;">delete</span> pDataSrc<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>I was especially lazy in that last listing actually, because I told Xerces to <em>adopt</em> my buffer which means it&#8217;ll free it for me when it&#8217;s finished with it. Curiously though, even a memory object needs a <em>system id</em> which is the purpose <span style="font-family: Courier New;">L&#8221;TwitterXML&#8221;</span> serves. With a <a href="http://xerces.apache.org/xerces-c/apiDocs-2/classDOMDocument.html" target="_blank">DOMDocument</a> in memory it was trivial to add the statuses to a list box.</p>
<p><a href="http://www.kierdugan.com/wp/wp-content/uploads/2010/03/XercesTest.jpg"><img class="aligncenter size-medium wp-image-59" title="XercesTest" src="http://www.kierdugan.com/wp/wp-content/uploads/2010/03/XercesTest-300x185.jpg" alt="" width="300" height="185" /></a></p>
<p>I was quite surprised at how complex a task I&#8217;d achieved given the effort I&#8217;d put in; hats off to both Xerces and libcurl. Now that I&#8217;d managed to list my tweets, naturally the next step is to try and submit one! So I made a new dialog for the occasion:</p>
<p><a href="http://www.kierdugan.com/wp/wp-content/uploads/2010/03/XercesTestPost.jpg"><img class="aligncenter size-full wp-image-60" title="XercesTestPost" src="http://www.kierdugan.com/wp/wp-content/uploads/2010/03/XercesTestPost.jpg" alt="" width="210" height="226" /></a></p>
<p>Clicking OK causes some magic to happen:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">int</span> CPostStatusDlg<span style="color: #008080;">::</span><span style="color: #007788;">DoStatusUpdate</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span><span style="color: #000040;">*</span> cszUrl <span style="color: #000080;">=</span>
        <span style="color: #FF0000;">&quot;http://api.twitter.com/1/statuses/update.xml&quot;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #666666;">// Attempt to initialise cURL.</span>
    CURL<span style="color: #000040;">*</span> curl <span style="color: #000080;">=</span> curl_easy_init <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>curl <span style="color: #000080;">==</span> <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span>
        <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #666666;">// Configure the authentication</span>
    CString strFmt<span style="color: #008080;">;</span>
    strFmt.<span style="color: #007788;">Format</span> <span style="color: #008000;">&#40;</span>_T<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;%s:%s&quot;</span><span style="color: #008000;">&#41;</span>, m_strUserName, m_strPassword<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    curl_easy_setopt <span style="color: #008000;">&#40;</span>curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    curl_easy_setopt <span style="color: #008000;">&#40;</span>curl, CURLOPT_USERPWD,  <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">char</span><span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>strFmt.<span style="color: #007788;">GetString</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #666666;">// Format the string entire in C form.</span>
    <span style="color: #0000ff;">char</span><span style="color: #000040;">*</span> szStatus <span style="color: #000080;">=</span> curl_easy_escape <span style="color: #008000;">&#40;</span>curl, m_strStatus.<span style="color: #007788;">GetString</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>,
        m_strStatus.<span style="color: #007788;">GetLength</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">char</span> szPostBody<span style="color: #008000;">&#91;</span><span style="color: #0000ff;">BUFSIZ</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
    <span style="color: #0000dd;">sprintf</span> <span style="color: #008000;">&#40;</span>szPostBody, <span style="color: #FF0000;">&quot;status=%s&quot;</span>, szStatus<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    curl_free <span style="color: #008000;">&#40;</span>szStatus<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #666666;">// Set up the HTTP connection and use the POST method</span>
    curl_easy_setopt <span style="color: #008000;">&#40;</span>curl, CURLOPT_POST,           <span style="color: #0000dd;">1L</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    curl_easy_setopt <span style="color: #008000;">&#40;</span>curl, CURLOPT_POSTFIELDSIZE,  <span style="color: #0000dd;">strlen</span> <span style="color: #008000;">&#40;</span>szPostBody<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    curl_easy_setopt <span style="color: #008000;">&#40;</span>curl, CURLOPT_POSTFIELDS,     szPostBody<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #666666;">// Finally, set the callback function and the URL.</span>
    CMemFile buffer<span style="color: #008080;">;</span>
    curl_easy_setopt <span style="color: #008000;">&#40;</span>curl, CURLOPT_WRITEFUNCTION, _CurlWriteCB<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    curl_easy_setopt <span style="color: #008000;">&#40;</span>curl, CURLOPT_WRITEDATA,     <span style="color: #000040;">&amp;</span>buffer<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    curl_easy_setopt <span style="color: #008000;">&#40;</span>curl, CURLOPT_URL,           cszUrl<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #666666;">// Now we can execute at last!</span>
    <span style="color: #0000ff;">int</span> nResponse <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
    CURLcode res <span style="color: #000080;">=</span> curl_easy_perform <span style="color: #008000;">&#40;</span>curl<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    curl_easy_getinfo <span style="color: #008000;">&#40;</span>curl, CURLINFO_RESPONSE_CODE, <span style="color: #000040;">&amp;</span>nResponse<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    curl_easy_cleanup <span style="color: #008000;">&#40;</span>curl<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #666666;">// Check for success</span>
    <span style="color: #0000ff;">return</span> nResponse<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>Boom! Tweet submitted!</p>
<p>In the above listing, the growable buffer and the callback are largely to just eat the output from libcurl because we don&#8217;t really care about it. CMemFile will free the memory it allocated when the function returns too, which saves hassle. I originally wrote all the code listings with Unicode in mind which is why they might appear to be a bit odd. libcurl is an ANSI C library so you may need to convert your strings for it to work. Thankfully Xerces includes <a href="http://xerces.apache.org/xerces-c/apiDocs-2/classXMLString.html" target="_blank">some basic support</a> because it uses Unicode internally.</p>
<p>Little victory indeed.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kierdugan.com/2010/03/25/twitter-me-xerces/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

