<?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>pamiętnik programisty &#187; Programowanie</title>
	<atom:link href="http://piotr.doniec.eu/devlog/category/programowanie/feed/" rel="self" type="application/rss+xml" />
	<link>http://piotr.doniec.eu/devlog</link>
	<description></description>
	<lastBuildDate>Wed, 28 Dec 2011 23:52:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>git cherry-pick is awesome</title>
		<link>http://piotr.doniec.eu/devlog/2011/11/git-cherry-pick-is-awesome/</link>
		<comments>http://piotr.doniec.eu/devlog/2011/11/git-cherry-pick-is-awesome/#comments</comments>
		<pubDate>Sun, 06 Nov 2011 12:51:44 +0000</pubDate>
		<dc:creator>pejotr</dc:creator>
				<category><![CDATA[Inne]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[problem-rozwiazanie]]></category>
		<category><![CDATA[problem-solution]]></category>
		<category><![CDATA[useful]]></category>

		<guid isPermaLink="false">http://piotr.doniec.eu/devlog/?p=634</guid>
		<description><![CDATA[Today I used git cherry-pick command for the first time, and I am really impressed. In my current project I&#8217;ve few branches, just for fixing/delopment. There are also a few common files like documentation, TODO &#8211; simple text files. Sometimes I came up with a genius idea and I want to put it in TODO [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_635" class="wp-caption alignleft" style="width: 202px"><a href="http://piotr.doniec.eu/devlog/wp-content/uploads/2011/11/git-logo.png"><img class="size-medium wp-image-635  " title="git-logo" src="http://piotr.doniec.eu/devlog/wp-content/uploads/2011/11/git-logo-300x74.png" alt="git cherry-pick logo" width="192" height="47" /></a><p class="wp-caption-text">GIT</p></div>
<p>Today I used git cherry-pick command for the first time, and I am really impressed. In my current project I&#8217;ve few branches, just for fixing/delopment. There are also a few common files like documentation, TODO &#8211; simple text files. Sometimes I came up with a genius idea and I want to put it in TODO file just not to forget. The problem is that I can&#8217;t guarantee that I will be working on <code>'master'</code> branch at that time. Using <code>cherry-pick</code> I was able to update &#8216;master&#8217; branch just with this one commit from other branch.<br />
One might say that instead of using <code>cherry-pick</code>I could first switch to &#8216;master&#8217; and made a change. But this have to be done immediatly, while cherry-picking can be deferred in time:</p>
<pre class="brush: cpp">
$ git checkout master
$ git cherry-pick -x aac5f43
</pre>
<p>where &#8222;aac5f43&#8243; is a part of commit SHA1 that should be picked. Commits information can be retrived using <code>git log</code> command.</p>
]]></content:encoded>
			<wfw:commentRss>http://piotr.doniec.eu/devlog/2011/11/git-cherry-pick-is-awesome/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Małoznany modyfikator [ dla scanf</title>
		<link>http://piotr.doniec.eu/devlog/2011/10/maloznany-modyfikator-dla-scanf/</link>
		<comments>http://piotr.doniec.eu/devlog/2011/10/maloznany-modyfikator-dla-scanf/#comments</comments>
		<pubDate>Wed, 19 Oct 2011 09:32:15 +0000</pubDate>
		<dc:creator>pejotr</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[tricky]]></category>

		<guid isPermaLink="false">http://piotr.doniec.eu/devlog/?p=617</guid>
		<description><![CDATA[Funkcja scanf z biblioteki standardowej C umożliwia odczyt i parsowanie danych z stdin zgodnie z określonym formatem. Większość modyfikatorów jest opisana na stronie cppreference, która nomen omen pojawia się jako pierwsza po wpisaniu &#8222;scanf&#8221; w wyszukiwarce. Jak się jednak okazuje nie są to wszystkie dostępne modyfikatory. Brakuje jednego istotnego, który umożliwia np. czytanie standardowego wejścia [...]]]></description>
			<content:encoded><![CDATA[<p>Funkcja scanf z biblioteki standardowej C umożliwia odczyt i parsowanie danych z stdin zgodnie z określonym formatem. Większość modyfikatorów jest opisana na <a href="http://www.cplusplus.com/reference/clibrary/cstdio/scanf/">stronie cppreference</a>, która nomen omen pojawia się jako pierwsza po wpisaniu &#8222;scanf&#8221; w wyszukiwarce. Jak się jednak okazuje nie są to wszystkie dostępne modyfikatory. Brakuje jednego istotnego, który umożliwia np. czytanie standardowego wejścia póki składa się z prawidłowych/dozwolonych znaków &#8211; tym modyfikatorem jest &#8222;[ ]&#8222;. W nawiasach należy umieścić wszystkie znaki które sanf może odczytać. W przypadku napotkania znaku niewystępującego w zbiorze, scanf zaprzestaje dalszego działania.<br />
Możliwe jest również zdefiniowanie zakresu poprzez wykluczenie niektórych znaków, do tego celu należy użyć &#8222;^&#8221;. Dzięki temu przy wykorzystaniu scanf można odczytać całe zdanie ignorując białe znaki za wyjątkiem znaku końca linii:</p>
<pre class="brush: cpp">
char str[512];
scanf(&quot; [^\n]&quot;, &amp;str);
</pre>
]]></content:encoded>
			<wfw:commentRss>http://piotr.doniec.eu/devlog/2011/10/maloznany-modyfikator-dla-scanf/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Methods for getting root access on Android phone</title>
		<link>http://piotr.doniec.eu/devlog/2011/04/methods-for-getting-root-access-on-android-phone/</link>
		<comments>http://piotr.doniec.eu/devlog/2011/04/methods-for-getting-root-access-on-android-phone/#comments</comments>
		<pubDate>Thu, 28 Apr 2011 13:43:41 +0000</pubDate>
		<dc:creator>pejotr</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[tricky]]></category>

		<guid isPermaLink="false">http://piotr.doniec.eu/devlog/?p=611</guid>
		<description><![CDATA[Recently I got more interested in Android platform. I was wondering what are methods to obtain &#8222;root&#8221; rights. After few minutes of googling I found two possible solutions. First method make use of udev bug. Basically this service does not check source of message, so it is possible to run code on behalf of root [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I got more interested in Android platform. I was wondering what are methods to obtain &#8222;root&#8221; rights. After few minutes of googling I found two possible solutions.<br />
First method make use of udev bug. Basically this service does not check source of message, so it is possible to run code on behalf of root user. Second method is a bit more sophisticated in my opinion. It purpose is to block adb from dropping root privileges to normal user. It is done by creating maximum number of processes and then restarting adb.<br />
More detailed information an sample code can be found here: http://intrepidusgroup.com/insight/2010/09/android-root-source-code-looking-at-the-c-skills/</p>
]]></content:encoded>
			<wfw:commentRss>http://piotr.doniec.eu/devlog/2011/04/methods-for-getting-root-access-on-android-phone/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to migrate from Mambo 4.5.1 to Joomla 1.6</title>
		<link>http://piotr.doniec.eu/devlog/2011/03/how-to-migrate-from-mambo-4-5-1-to-joomla-1-6/</link>
		<comments>http://piotr.doniec.eu/devlog/2011/03/how-to-migrate-from-mambo-4-5-1-to-joomla-1-6/#comments</comments>
		<pubDate>Sat, 26 Mar 2011 22:39:33 +0000</pubDate>
		<dc:creator>pejotr</dc:creator>
				<category><![CDATA[Inne]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[issue]]></category>
		<category><![CDATA[joomla]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[tricky]]></category>

		<guid isPermaLink="false">http://piotr.doniec.eu/devlog/?p=584</guid>
		<description><![CDATA[My task was to migrate database from Mambo 4.5.1 to newest Joomla version which is now 1.6. I didn&#8217;t have to migrate any additional components data, just core functionality. At first I thought I will be an easy task, but then a few difficulties showed. Below I provide step which took me to happy end. [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://piotr.doniec.eu/devlog/wp-content/uploads/2011/03/joomla-logo.png"><img class="alignleft size-medium wp-image-604" title="joomla-logo" src="http://piotr.doniec.eu/devlog/wp-content/uploads/2011/03/joomla-logo-300x205.png" alt="" width="210" height="144" /></a>My task was to migrate database from Mambo 4.5.1 to newest Joomla version which is now 1.6. I didn&#8217;t have to migrate any additional components data, just core functionality. At first I thought I will be an easy task, but then a few difficulties showed. Below I provide step which took me to happy end.<br />
<span id="more-584"></span></p>
<ol>
<li><strong>1. Copy database tables and Mambo code from remote server to local system</strong>. I used WAMP to do all migration. By doing that the site was still online, while I was doing some research. If for some reason you don&#8217;t have access to phpMyAdmin or any other database client, use <a href="http://sidu.sourceforge.net/sidu/">SIDU 3.2 DB Web GUI</a></li>
<li><strong>2. Convert SQL file to UTF8 encoding.</strong>You can do this using i.e. Notepad++ &#8211; use Convert to UTF8 (without BOM).<br />
Also change tables encoding to UTF8. This operation will cause problems with &#8216;ocp_core_acl_aro&#8217; table <code>"#1071, Specified key was too long; max key length is 1000 bytes"</code>. Rewrite it as below
<pre class="brush: sql">
CREATE TABLE `ocp_core_acl_aro` (
`aro_id` int(11) NOT NULL auto_increment,
`section_value` varchar(240) NOT NULL default &#039;0&#039;,
`value` varchar(240) NOT NULL default &#039;&#039;,
`order_value` int(11) NOT NULL default &#039;0&#039;,
`name` varchar(255) NOT NULL default &#039;&#039;,
`hidden` int(11) NOT NULL default &#039;0&#039;,
PRIMARY KEY  (`aro_id`),
UNIQUE KEY `ocp_gacl_section_value_value_aro` (`section_value`(100),`value`(75)),
UNIQUE KEY `section_value_value_aro` (`section_value`(100),`value`(75)),
KEY `hidden_aro` (`hidden`),
KEY `ocp_gacl_hidden_aro` (`hidden`)
) ENGINE=MyISAM AUTO_INCREMENT=13 DEFAULT CHARSET=utf8
</pre>
</li>
<li><strong>3. Migrate to Mambo 4.5.2</strong> Create local database for Mambo 4.5.2 and use utf8_general_ci for connection and comparison.  Download and extract Mambo 4.5.2 to webserver directory. Change db settings in configuration.php and apply sql script upgrade451to452.sql from installation\sql direcotry</li>
<li><strong>4. Install Joomla 1.5 but do not load sample data</strong></li>
<li><strong>5. Install mtwmigrator for Joomla 1.5</strong> You can download it here <a href="http://www.matware.com.ar/downloads/joomla/mtwmigrator/mtwmigrator-v0-2-1.html">mtwmigrator-v0-2-1</a>. Run component and go to Preference. Set db name, location, login and password. Select data you want to migrate and launch migration process. After this step you should have all data from Joomla 1.0 availbale in new installation on Joomla 1.5</li>
<li><strong>6. Migrate to Joomla 1.6 using jUpgrade. </strong>You can download it here <a href="http://www.matware.com.ar/downloads/joomla/jupgrade.html">jUpgrade</a>. All you have to do is to install it within Joomla 1.5 and start. If some problem occurs try enabling Debuging in jUpgrade</li>
<p>Now, you should have new installation of Joomla 1.6 created for you and available in jUpgrade dir in Joomla 1.5 directory. New tables were created in same database as Joomla 1.5, so depending on needs, final step might be to dump those tables and move to new, dedicated location.</ol>
]]></content:encoded>
			<wfw:commentRss>http://piotr.doniec.eu/devlog/2011/03/how-to-migrate-from-mambo-4-5-1-to-joomla-1-6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Problem with timestamps in libnetfilter_queue solved</title>
		<link>http://piotr.doniec.eu/devlog/2010/12/problem-with-timestamps-in-libnetfilter_queue-solved/</link>
		<comments>http://piotr.doniec.eu/devlog/2010/12/problem-with-timestamps-in-libnetfilter_queue-solved/#comments</comments>
		<pubDate>Mon, 27 Dec 2010 21:45:09 +0000</pubDate>
		<dc:creator>pejotr</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[issue]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[solution]]></category>
		<category><![CDATA[tricky]]></category>

		<guid isPermaLink="false">http://piotr.doniec.eu/devlog/?p=561</guid>
		<description><![CDATA[My BSc Thesis is to implement steganography algorithm that use VoIP packets as a transport. The main aim is to modify delay of RTP packets without noticeable impact on transmission quality. I create hidden channel by sending two packets that average delay is 20ms. For example if we send 1 packet 10ms after previous and [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://piotr.doniec.eu/devlog/wp-content/uploads/2010/12/netfilter-logo2.png"><img src="http://piotr.doniec.eu/devlog/wp-content/uploads/2010/12/netfilter-logo2.png" alt="" title="netfilter-logo2" width="265" height="72" class="alignleft size-full wp-image-576" /></a>My BSc Thesis is to implement steganography algorithm that use VoIP packets as a transport. The main aim is to modify delay of RTP packets without noticeable impact on transmission quality. I create hidden channel by sending two packets that average delay is 20ms. For example if we send 1 packet 10ms after previous and second 30ms after first the average delay is 20ms. Calling parties will not notice so small difference, but software should recognize such situation as sending the bit with value 1. When we want to send bit 0 we can just switch delays, then first packet will be sent after 30ms and another 10ms later. The time the packet was received is very important for Receiver. The network can add a random delay but Receiver should still be able to collect all sent bits.<br />
For implementation I used libnetfilter_queue and iptables. This two powerful tools are more than enough for my need. Everything was fine until and got to point where I had to read packet delay. Although libnetfilter_queue provide function for reading timestamp when packet was queued (nfq_get_timestamp) it&#8217;s not working without additional tweaks. For kernel performance reason timestamping network packets is by default disabled. After digging through kernel source I found functions responsible from toggling this setting, it&#8217;s a net_enable_timestamp() and net_disable_timestamp(). I had no idea how to execute each of them but MarkR from stackoverflow.org helped me. There is no need to enable timestamping globally for all packets instead it can be enabled for particular socket by using setsockopt. The call sequence is then setsockopt() -> sock_setsockopt() -> sock_enable_timestamp(&#8230;) -> net_enable_timestamp(). It is possible to get file descriptor connected with particular queue and treat it as it would be socket. This means that following code is valid and can be used to enable timestamping incoming packets:</p>
<pre class="brush: cpp">
int ena = 1;
if( setsockopt(queuefd, SOL_SOCKET, SO_TIMESTAMP, &amp;ena, sizeof(ena)) )
{
    SYS_LOG(E_WARNING, &quot;Unable to enable timestamping&quot;);
}
</pre>
<p>and then in queue handle function:</p>
<pre class="brush: cpp">
int handle_queue(struct nfq_q_handle *pQh, struct nfgenmsg *pNfmsg, struct nfq_data *pNfa, void *pData)
{
    struct nfqnl_msg_packet_hdr *ph;
    struct timeval tv;
    int id;

    ph = nfq_get_msg_packet_hdr(pNfa);
    if(ph)
    {
        id = ntohl(ph-&gt;packet_id);
    }

    nfq_get_timestamp(pNfa, &amp;tv);
    /* do sth. with read timestamp */

    return nfq_set_verdict(pQh, id, NF_ACCEPT, 0, NULL);
}
</pre>
<p>This is a solution for a issue, that as far as i know, have not been solved since this post:<br />
&#8222;So far the biggest issues I&#8217;ve run into are that marking doesn&#8217;t work in 2.6.15 (I think it should in 2.6.16), and I can&#8217;t seem to ever read the timestamp for a packet, no matter  hat hook it comes in on.  I&#8217;ve just been using gettimeofday for that for now.&#8221;<br />
<a href="http://lists.netfilter.org/pipermail/netfilter-devel/2006-February/023490.html">http://lists.netfilter.org/pipermail/netfilter-devel/2006-February/023490.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://piotr.doniec.eu/devlog/2010/12/problem-with-timestamps-in-libnetfilter_queue-solved/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Z C++ zagadka nr 5</title>
		<link>http://piotr.doniec.eu/devlog/2010/08/z-c-zagadka-nr-5/</link>
		<comments>http://piotr.doniec.eu/devlog/2010/08/z-c-zagadka-nr-5/#comments</comments>
		<pubDate>Thu, 05 Aug 2010 20:22:26 +0000</pubDate>
		<dc:creator>pejotr</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[tricky]]></category>

		<guid isPermaLink="false">http://piotr.doniec.eu/devlog/?p=549</guid>
		<description><![CDATA[Wrednie podchwytliwe zadanie czasami w tej czy innej postaci spotykane na różnych testach ze znajomości języka. Jaki będzie efekt wykonania poniższego programu: #include &#60;iostream&#62; int foo(int x, int y) { return x + y; } int main() { int z, k; z = 10; k = foo(z = 20, z += 1); std::cout &#60;&#60; k [...]]]></description>
			<content:encoded><![CDATA[<p>Wrednie podchwytliwe zadanie czasami w tej czy innej postaci spotykane na różnych testach ze znajomości języka.<br />
Jaki będzie efekt wykonania poniższego programu:</p>
<pre class="brush: cpp">
#include &lt;iostream&gt;

int foo(int x, int y)
{
    return x + y;
}

int main()
{
    int z, k;
    z = 10;
    k = foo(z = 20, z += 1);
    std::cout &lt;&lt; k &lt;&lt; std::endl;
}
</pre>
<p>Najłatwiej zweryfikować korzystając z kompilatora. Na rozważanie przyczyna takie czy innego wyniku nie warto poświęcać zbyt wiele czasu, ponieważ dodanie flagi -Wall rozwiewa wszystkie wątpliwości:</p>
<blockquote><p>
zadanie.cpp: In function &#8216;int main()&#8217;:<br />
zadanie.cpp:14: warning: operation on &#8216;z&#8217; may be undefined
</p></blockquote>
<p>Zatem poprawna odpowiedź na pytanie: &#8222;to zależy od kompilatora, sprzętu, systemu&#8221;</p>
]]></content:encoded>
			<wfw:commentRss>http://piotr.doniec.eu/devlog/2010/08/z-c-zagadka-nr-5/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Z C++ zagadka nr 4</title>
		<link>http://piotr.doniec.eu/devlog/2010/07/z-c-zagadka-nr-4/</link>
		<comments>http://piotr.doniec.eu/devlog/2010/07/z-c-zagadka-nr-4/#comments</comments>
		<pubDate>Sun, 25 Jul 2010 12:50:24 +0000</pubDate>
		<dc:creator>pejotr</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[common error]]></category>
		<category><![CDATA[tricky]]></category>

		<guid isPermaLink="false">http://piotr.doniec.eu/devlog/?p=532</guid>
		<description><![CDATA[Mając przedstawioną poniżej strukturę danych i kontener zawierający wskaźniki, wykonać operację/metodę methodA na rzecz obiektu obj_ posługując się iteratorem: class Foo { public: methodA() { printf(&#34;Wykonano...\n&#34;); } } struct data_t { int i_; Foo* obj_; } std::list&#60;data_t*&#62; data_; for(std::list&#60;data_t*&#62;::iterator i = data_.begin(); i != data_.end(); i++ ) { // operacje } W jaki sposób wykonać [...]]]></description>
			<content:encoded><![CDATA[<p>Mając przedstawioną poniżej strukturę danych i kontener zawierający wskaźniki, wykonać operację/metodę methodA na rzecz obiektu obj_ posługując się iteratorem:</p>
<pre class="brush: cpp">
class Foo {
public:
  methodA() {
    printf(&quot;Wykonano...\n&quot;);
  }
}

struct data_t {
  int i_;
  Foo* obj_;
}

std::list&lt;data_t*&gt; data_;

for(std::list&lt;data_t*&gt;::iterator i  = data_.begin(); i != data_.end(); i++ ) {
   // operacje
}
</pre>
<p>W jaki sposób wykonać blok operacji ? Możliwości mamy kilka:</p>
<pre class="brush: cpp">
/* 1 */ i-&gt;obj_-&gt;methodA();
/* 2 */ *i-&gt;obj_-&gt;methodA();
/* 3 */ (*i)-&gt;obj_-&gt;methodA();
</pre>
<p>Rozwiązanie zagadki jest proste, ale wymaga znajomości priorytetów operatorów. Pierwsze wywołania jest całkowicie błędne, ponieważ lista przecowuje wskaźniki do strkutury, a nie samą strukturę. Zatem należy najpier wyłuskać strukturę znajdującą się pod wskazywanym adresem i dopiero wtedy wykonać metodę. Okazuje się że rowiązania 2 również jest nie poprawne, właśnie ze względu na priorytety operatorów. Dopiero numer 3 daje zamierzony efekt. Na szczęście błąd ujawnia się na etapie kompilacji&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://piotr.doniec.eu/devlog/2010/07/z-c-zagadka-nr-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VIM, spacje zamiast wcięć</title>
		<link>http://piotr.doniec.eu/devlog/2010/07/vim-spacje-zamiast-wciec/</link>
		<comments>http://piotr.doniec.eu/devlog/2010/07/vim-spacje-zamiast-wciec/#comments</comments>
		<pubDate>Wed, 07 Jul 2010 21:14:03 +0000</pubDate>
		<dc:creator>pejotr</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://piotr.doniec.eu/devlog/?p=511</guid>
		<description><![CDATA[Charakterystyczną cechą języka Python jest oddzielanie bloków kodu za pomocą wcięć. Z tego powodu są one niezmiernie istotne, a szukanie błędu powstałego przez źle umieszczone wcięcie, jeśli nie jest sygnalizowane przez interpreter może być bardzo czasochłonne a czasami wręcz frustrujące. Jakiś czas temu spotkałem się z takim problemem, który wynikł z używania 2 edytorów na [...]]]></description>
			<content:encoded><![CDATA[<p>Charakterystyczną cechą języka Python jest oddzielanie bloków kodu za pomocą wcięć. Z tego powodu są one niezmiernie istotne, a szukanie błędu powstałego przez źle umieszczone wcięcie, jeśli nie jest sygnalizowane przez interpreter może być bardzo czasochłonne a czasami wręcz frustrujące. Jakiś czas temu spotkałem się z takim problemem, który wynikł z używania 2 edytorów na 2 różnych maszynach. Na Windows korzystałem zamiennie z Vim oraz Programmers Notepad (tab = 4 spacje), pod linuxem wyłącznie z Vim bo tylko na tyle pozwalał interface konsolowy.<br />
W pewnym momencie doszło do kolizji. Z jakiegoś powodu część wcięć przesunęła się w lewo &#8211; czyli znikły. Na całe szczęście 90% błędów zostało wykrytych przez interpreter. Od razu zaznaczam że nie przeprowadziłem pełnej analizy problemu, ale coś mi podpowiadało że to wina Tab w Vim. Poniżej przedstawiam w jaki sposób zamieniać wszystkie tabulacje na 4 spacje. Komendy można umieścić w .vimrc (linux) czy też w _vimrc jeśli korzystamy z Windows:</p>
<pre class="brush: python">
set tabstop=4
set shiftwidth=4
set expandtab
</pre>
<p>Na sam koniec warto dodać, że mimo iż Vim może być postrzegany jako stary edytor, trudny w użyciu a posługują się nim tylko starzy wyjadacze-programiści z poprzedniej epoki, to ma on wiele funkcji których nie oferuje nawet Notepad++, a programowanie bez odrywania rąk od klawiatury jest o wiele mniej męczące. Polecam cheatsheet: http://www.qitty.net/lnx/vim-cheatsheet.png</p>
]]></content:encoded>
			<wfw:commentRss>http://piotr.doniec.eu/devlog/2010/07/vim-spacje-zamiast-wciec/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>.NET słowa kluczowe out,ref</title>
		<link>http://piotr.doniec.eu/devlog/2010/05/net-slowa-kluczowe-outref/</link>
		<comments>http://piotr.doniec.eu/devlog/2010/05/net-slowa-kluczowe-outref/#comments</comments>
		<pubDate>Sat, 08 May 2010 10:24:32 +0000</pubDate>
		<dc:creator>pejotr</dc:creator>
				<category><![CDATA[C#/.NET]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[beginning c#]]></category>
		<category><![CDATA[keywords]]></category>

		<guid isPermaLink="false">http://piotr.doniec.eu/devlog/?p=490</guid>
		<description><![CDATA[Znalazłem ostatnio trochę czasu aby dokładniej przyjrzeć się .NET i na własnej skórze przekonać się czy jest warty więcej niż Java. Dotąd napisałem tylko dwa proste programik wykorzystują tę platformę &#8211; aplikację MDI obsługująca skromną bazę danych przechowującą informację o osobach opartą na plikach binarnych, oraz obsługę portu rs232. Pamiętam że sposób programowania nie powalił [...]]]></description>
			<content:encoded><![CDATA[<p>Znalazłem ostatnio trochę czasu aby dokładniej przyjrzeć się  .NET i na własnej skórze przekonać się czy jest warty więcej niż Java. Dotąd napisałem tylko dwa proste programik wykorzystują tę platformę &#8211; aplikację MDI obsługująca skromną bazę danych przechowującą informację o osobach opartą na plikach binarnych, oraz obsługę portu rs232. Pamiętam że sposób programowania nie powalił mnie wtedy na kolana, przypominało to raczej tylko trochę uproszczone C++. Oczywiście skorzystałem z całkiem fajnego mechanizmu właściwości(properties) i upraszczającej życie pętli foreach, stworzyłem nawet własną kontrolkę, ale wszystko to było robione w pośpiechu i nie pozwoliło wniknąć głębiej. Teraz postanowiłem nadrobić zaległości i jestem mile zaskoczony.<br />
<span id="more-490"></span><br />
To co tak naprawdę skłoniło mnie do wypożyczenia książki i studiowania jej od samego początku to możliwość łączenia kodu napisanego w C++(/CLI) z kodem zarządzanym napisanym w .NET. Miło jest móc połączyć wysokopoziomowe programowanie logiki aplikacji z niskopoziomowym dostępem do funkcji systemu operacyjnego Windows takich jak dostęp do kamery czy przechwytywanie komunikatów.<br />
Ponieważ książkę czytam od deski, zostałem zmuszony do przypomnienia podstawowych konstrukcji programistycznych takich jak metody czy proste klasy, ale poznałem przy tym kilka ciekawych słów kluczowych umożliwiających kontrolowanie modyfikacji danych.</p>
<p><strong>Modyfikator out</strong><br />
Modyfikatorem out można oznaczyć dowolną liczbę parametrów metody. Nie ma przy tym znaczenia kolejność, parametry zmodyfikowane przez out mogą wystąpić zarówno na początku listy w środku jak i na końcu. To słowo kluczowe definiuje tzw. parametr wyjściowy. Wykonanie funkcji wymaga zapisania wartości do parametru wyjściowego. </p>
<pre class="brush: csharp">
        public static void Dodawanie(out int sum, int x, int y, out int ssum)
        {
            sum = x + y;
            ssum = sum * sum;
        }
</pre>
<p>Jeśli kompilator nie znajdzie prawidłowego(co można wymusić komentując linię ssum = sum*sum) przypisania wygeneruje błąd i poinformuje nas o tym komunikatem: </p>
<blockquote><p>&#8222;The out parameter &#8216;ssum&#8217; must be assigned to before control leaves the current method&#8221;</p></blockquote>
<p>Modyfikator out, może trochę przypominać mechanizm znany z C polegający na przekazywaniu wskaźnika jako parametru funkcji. Jednak w przypadku C# mamy pewność że po wykonaniu podprogramu, w parametrze wyjściowym znajdzie się jakąś wartość, co chroni nas przed nieprzyjemnym komunikatem <em>&#8222;Segmentation fault&#8221;</em>. Istnieje jeszcze jedna różnica wpływająca na korzyść platformy .NET, mianowicie sposób wywołania. Nie ma tu magicznych zaklęć nie trzeba się domyślać który parametr to wskaźnik i jak został przekazany, ponieważ trzeba to jawnie określić. Kompilator umożliwi uruchomienie programu tylko wtedy gdy wszystkie wywołania funkcji zostaną opisane zgodnie z ich deklaracjami/definicjami, znakomicie wpływa to na czytelność kodu:</p>
<pre class="brush: csharp">
        static void Main(string[] args)
        {
            int sum, ssum;
            int a = 5, b = 6;

            Dodawanie(out sum, a, b, ssum);       // FAIL !
            Dodawanie(out sum, a, b, out ssum); // OK !

            Console.WriteLine(&quot;Suma {0} + {1} = {2}, ({0} + {1})^2 = {3}&quot;, a, b, sum, ssum);
            Console.ReadLine();
        }
</pre>
<p><strong>Modyfikator ref</strong><br />
Działanie modyfikatora ref również jest związane z wywołaniem metod. Jednakże jego zastosowanie ma sens tylko w odniesieniu do obiektów które w łańcuchu dziedziczenia nie mają klasy System.ValueType, a więc takich które tworzone są na stercie i nie są przekazywane przez wartość ale przez referencję. Podobnie jak w przypadku Javy, modyfikacje wykonane na takim obiekcie pozostają aktualne po zakończeniu metody, o czym napisałem we wpisie <a href="http://piotr.doniec.eu/devlog/2009/03/pass-by-value-w-javie/">Pass-by-value w javie</a>. Dla przypomnienia: tak naprawdę przekazywana jest nie referencja a jej kopia, z tego powodu dozwolona jest zmiana stanu obiektu ale przypisanie referencji do innego obiektu już nie. Aby lepiej zrozumieć zagadnienie przedstawiam prosty przykład prezentujący wspomnianą funkcjonalność:</p>
<pre class="brush: csharp">
class Punkt
{
  public int x;
  public int y;
}

class Program
{

  public static void CopyReference(Punkt p)
  {
    p.x = 0;
    p.y = 0;

    p = new Punkt();
    p.x = 200;
    p.y = 200;
  }

static void Main(string[] args)
{
  Punkt p1 = new Punkt();
  p1.y = 100;
  p1.x = 100;

  Console.WriteLine(&quot;Przed wykonaniem CopyReference: p1.x = {0}, p1.y = {1}&quot;, p1.x, p1.y);
  CopyReference(p1);
  Console.WriteLine(&quot;Po wykonaniem CopyReference: p1.x = {0}, p1.y = {1}&quot;;, p1.x, p1.y);
  Console.ReadLine();

  }
}
</pre>
<p>W wyniku wykonania programu powinniśmy zobaczyć na ekranie następujący wynik:</p>
<blockquote><p>
Przed wykonaniem CopyReference: p1.x = 100, p1.y = 100<br />
Po wykonaniem CopyReference: p1.x = 0, p1.y = 0
</p></blockquote>
<p>Aby osiągnąć zamierzone działanie wystarczy dodać modyfikator ref, zarówno do definicji metody, jak i do jej wywołania pdobnie jak ma to miejsce w przypadku &#8222;out&#8221;:</p>
<pre class="brush: csharp">
public static void OrigReference(ref Punkt p)
{
  p.x = 0;
  p.y = 0;

  p = new Punkt();
  p.x = 200;
  p.y = 200;
}
</pre>
<p>Po wykonaniu tak zmodyfikowanej metody, pola x oraz y obiektu p1 będą przechowywały wartość (200, 200)<br />
AFAIK w Javie takich możliwości nie ma, może konstrukcje takie nie są szczególnie przydatne, ale w .NET w razie czego są i można je wykorzystać co pozytywnie wpływa na moja dotychczasową ocenę tej platformy.</p>
]]></content:encoded>
			<wfw:commentRss>http://piotr.doniec.eu/devlog/2010/05/net-slowa-kluczowe-outref/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Uruchamianie metod klas w nowych wątkach w c++ i pthreads</title>
		<link>http://piotr.doniec.eu/devlog/2010/04/uruchamianie-metod-klas-w-nowych-watkach-w-c-i-pthreads/</link>
		<comments>http://piotr.doniec.eu/devlog/2010/04/uruchamianie-metod-klas-w-nowych-watkach-w-c-i-pthreads/#comments</comments>
		<pubDate>Tue, 06 Apr 2010 10:47:17 +0000</pubDate>
		<dc:creator>pejotr</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[pthreads]]></category>
		<category><![CDATA[qnx]]></category>
		<category><![CDATA[tricky]]></category>
		<category><![CDATA[wielowątkowość]]></category>

		<guid isPermaLink="false">http://piotr.doniec.eu/devlog/?p=471</guid>
		<description><![CDATA[Podczas pisania kolejnego projektu w języku c++ natknąłem się na interesujący problem. Program docelowo miał działać na systemie czasu rzeczywistego zatem jego celem było również zapoznanie z różnymi mechanizmami RTOS. Pierwszy problem pojawił się przy korzystaniu z mechanizmu wielowątkowości, pewnie byśmy się nie dowiedzieli o jego istnieniu gdybyśmy nie zdecydowali się na programowanie obiektowe, ale [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://piotr.doniec.eu/devlog/wp-content/uploads/2010/04/logo.gif" alt="qnx_rtos" title="qnx_rtos" width="106" height="45" class="alignright size-full wp-image-483" />Podczas pisania kolejnego projektu w języku c++ natknąłem się na interesujący problem. Program docelowo miał działać na systemie czasu rzeczywistego zatem jego celem było również zapoznanie z różnymi mechanizmami RTOS. Pierwszy problem pojawił się przy korzystaniu z mechanizmu wielowątkowości, pewnie byśmy się nie dowiedzieli o jego istnieniu gdybyśmy nie zdecydowali się na programowanie obiektowe, ale po kolei&#8230;<br />
<span id="more-471"></span><br />
Każdy kto programował w C++ korzystając z biblioteki Boost::Threads napewno wie że aby uruchomić metodę obiektu w nowym wątku wystarczy przeciążyć operator () i każdy obiekt takiej klasy zaczyna z powodzeniem udawać funkcję. Dzięki temu można taki obiekt przekazać do konstruktora boost::thread. Poniższy przykład obrazuje taką sposób działania:</p>
<pre class="brush: cpp">
// Copyright (C) 2001-2003
// William E. Kempf
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation.  William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided &quot;as is&quot; without express or implied warranty.

#include &lt;boost/thread/thread.hpp&gt;;
#include &lt;;boost/thread/xtime.hpp&gt;;
#include &lt;iostream&gt;;

struct thread_alarm
{
    thread_alarm(int secs) : m_secs(secs) { }
    void operator()()
    {
        boost::xtime xt;
        boost::xtime_get(&amp;xt, boost::TIME_UTC);
        xt.sec += m_secs;

        boost::thread::sleep(xt);

        std::cout &lt;&lt; &quot;alarm sounded...&quot; &lt;&lt; std::endl;
    }

    int m_secs;
};

int main(int argc, char* argv[])
{
    int secs = 5;
    std::cout &lt;&lt; &quot;setting alarm for 5 seconds...&quot; &lt;&lt; std::endl;
    thread_alarm alarm(secs);
    boost::thread thrd(alarm);
    thrd.join();
}
</pre>
<p>Jednak ten sposób nie działa w przypadku korzystania z natywnego mechanizmu wielowątkowości dostępnego w każdym systemie *nix. Biblioteka pthreads nie radzi sobie z wywołaniem przeciążonego operatora (). Problem trzeba było rozwiązać jak najszybciej, żeby projekt mógł ruszy dalej. Dlatego powstał ten sprytny &#8222;work-around&#8221; umożliwiający uruchomienie dowolnej metody obiektu w nowym wątku. Jest to właściwie funkcja proxy, takie proste a ułatwia życie:</p>
<pre class="brush: cpp">
template&lt;class T&gt;
struct ThreadParams
{
	T *obj;
	void *params;
};

template&lt;class T, void* (T::*method)(void*)&gt;
void* run_thread(void *params)
{
	ThreadParams&lt;T&gt; *t = static_cast&lt;ThreadParams&gt;&lt;T*&gt;(params);
	T* obj = static_cast&lt;T*&gt;(t-&gt;obj);
	(obj-&gt;*method)(t-&gt;params);
	return NULL;
}
</pre>
<p>Dodatkowy wkład pracy jaki należy włożyć aby wykorzystać powyższy kod ogranicza się właściwie tylko do wypełnienia struktury ThreadParams:</p>
<pre class="brush: cpp">
class Test
{
public:
	void* fun(void* params) {
	printf(&quot;Hello World! \n&quot;);
	printf(&quot;Params: %d\n&quot;, reinterpret_cast&lt;int&gt;(params));
	pthread_exit(NULL);
	}
 };

 int main() {

	pthread_t tid;
	void* status;
	Test test;
	ThreadParams&lt;Test&gt; params;

	params.obj = &amp;test;
	params.params = reinterpret_cast&lt;void&gt;(123);

	pthread_create(&amp;tid, NULL, run_thread&lt;Test, &amp;Test::fun&gt;, (void*)(&amp;params));
	pthread_join(tid, &amp;status);
 }
</pre>
]]></content:encoded>
			<wfw:commentRss>http://piotr.doniec.eu/devlog/2010/04/uruchamianie-metod-klas-w-nowych-watkach-w-c-i-pthreads/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

