Category Archives: Programming languages

All about programming languages, in paritcular OO-related ones

Using online music services with Ruby

[Or : Streaming Rhapsody or last.fm with Ruby]

Ruby has excellent libraries (HTTP, SSL, SOAP, XML, etc.) that can be used to write your own music player for streaming music from online services like Rhapsody or last.fm – so why not use them? Here are code snippets to help you getting started! They show you…

  • …how to make a HTTPS GET or POST request using SSL (https://…)
  • …how to easily parse the XML response of such a request
  • …how to stream music data (e.g. MP3) from some HTTP URL and how to pipe that stream data to another process (e.g. mplayer) for playing it back while streaming
  • …how to use SOAP requests with custom SSL certificates (https://…)
  • …how to encrypt/decrypt 64-bit DES ECB data

My own Ruby (1.8)-based Rhapsody player has 400 lines of Ruby code, my lasm.fm player has 200 lines of Ruby code  –   Do you think other languages can do better 😉 ?

Using HTTPS POST and SSL (HTTPS GET works similar using the Net::HTTP::Get class)

require 'net/http'
require 'net/https'

dict['api_key'] = @apikey
url = "https://someurl"

uri = URI.parse(url)
sock = Net::HTTP.new(uri.host, uri.port)
sock.use_ssl = true

req = Net::HTTP::Post.new(url)
req.set_form_data(dict)
res = sock.start{|http| http.request(req) }
puts res.body

Parsing XML response data

require 'rexml/document'
res = http_post( {'method'=> 'radio.getPlaylist', 'sk' => @sk })

doc = REXML::Document.new(res)

printf("%-30s %-50s %-40sn", "title", "album", "creator")
doc.elements.each("*/*/*/track") do |element|
  title    = element.elements["title"].text
  album    = element.elements["album"].text
  creator  = element.elements["creator"].text
  location = element.elements["location"].text
  image    = element.elements["image"].text
  printf("%-30s %-50s %-40sn", title, album, creator)
end

Streaming HTTP music data  (e.g. MP3) and piping it to another process (e.g. mplayer)

    uri = URI.parse(url)
    Net::HTTP.start(uri.host) do |http|
      http.request_get(uri.path) do |resp|
        pipe = IO.popen("mplayer -cache 256 -", "w")
        resp.read_body do |segment|
          if segment.length > 0
            pipe.write(segment)
          end
        end
        pipe.close
      end
    end

Of course, you can always pipe using bash..

macbook-pro:~ nero$ lastfm.rb | mplayer -cache 64 -

...however this wouldn't allow you to write something else to STDOUT except the music data.

Using SOAP requests and custom SSL certificates

require 'openssl'
require "rubygems"
gem "httpclient", "2.1.5.2"
gem 'soap4r'
require 'soap/rpc/driver'

driverPlay = SOAP::RPC::Driver.new('https://someurl', 'urn:someurn')
driverPlay.options["protocol.http.ssl_config.verify_mode"] = nil
driverPlay.options["protocol.http.ssl_config.client_cert"] = File.join(@dir, "somefile.cert.pem")
driverPlay.options["protocol.http.ssl_config.client_key"] = File.join(@dir, "somefile.key.pem")
driverPlay.return_response_as_xml = true
# define some method
driverPlay.add_method('startPlaybackSession', 'developerKey', 'cobrandId', 'logon', 'password', 'clientType')

Using 64-bit DES ECB encryption
(the key is to use ‘cipher.padding = 0’  – it took me 2 hours to figure that out …)

  require 'openssl'
  def testDES
    puts '*** TESTDES ***'
    key         = "x01x23x45x67x89xabxcdxef"
    plain       = "x01x23x45x67x89xabxcdxe7"
    cryptdata   = "xc9x57x44x25x6ax5exd3x1d"

    puts "key      = " + key.unpack("H*").to_s
    puts "plain    = " + plain.unpack("H*").to_s
    #puts OpenSSL::Cipher.ciphers

    puts "encrypt..."
    cipher = OpenSSL::Cipher::Cipher.new('des-ecb')
    cipher.encrypt
    cipher.key = key
    cipher.padding = 0
    res = cipher.update(plain)
    puts "res      = " + res.unpack("H*").to_s
    puts "crypted  = " + cryptdata.unpack("H*").to_s

    puts "decrypt..."
    cipher.decrypt
    res = cipher.update(res) + cipher.final
    puts "res      = " + res.unpack("H*").to_s
    puts "plain    = " + plain.unpack("H*").to_s

    puts "triple..."
    cipher.decrypt
    plain = cipher.update(plain) + cipher.final
    cipher.encrypt
    cipher.key = plain
    plain = cipher.update(plain)
    cipher.decrypt
    cipher.key = key
    res = cipher.update(plain) + cipher.final
    puts "res      = " + res.unpack("H*").to_s
  end





	

Pascal is dead – long lives FreePascal!

lazarus

You develop software for the consumer market in a professional manner? But you cannot afford a team of 30 developers? Your code changes quickly? And at the end you need to deliver your products to your customers, not just prototypes, right?

Don’t take me wrong, we have been using several programming languages over the years (including C++, Java, Python) and still use them all over the time. I rather think the general idea is that e.g. C++ is not always the right choice – Here’s what you get if you use FreePascal/Lazarus:

  • FreePascal is *not* just Pascal – you get a 100% programming OO-language with objects, classes, generics, interfaces, type-saftety and a clean and easy syntax like Java or C# – everything in a compiler.
    You might ask: Does it have the same quality like gcc or VC++? We think: YES.
  • FreePascal is multi-platform – after you wrote your application for Windows, it will run without modifications on the Mac – natively.
  • FreePascal is extendable – you can easily add shared libraries written in C or any other language.
  • Lazarus is *not* just another IDE – you get a multi-platform integrated source code editor including syntax checking, code completion, refactoring tools, and with an integrated WYSIWYG user interface editor for managing your application’s user interface:  menus, windows, text labels, edit fields, buttons, etc. – including ‘layout manager’ – everything with full preview and without recompiling your code!
  • Lazarus LCL (component library) is a multi-platform, Unicode-capable GUI library – after you designed your user interface on Window, it will run without any modifications on the Mac.
    You might ask: Does this LCL have the quality of something like wxWidgets or QT?  We think: YES.
  • The ‘edit-compile-run‘ cycle is *fast* – you don’t have to wait for the executables, they are just there after hitting the compilation button.
  • Needless to say: it is Open Source – If you find a bug, it’s often easy to fix it yourself. Plus, the source of your issue is just a click away (CTRL+mouse click shows the IDE/GUI library code of the clicked method).
    It comes with a modified GPL license which means you are fully allowed to build and ship your commerical applications with it, and of course without having to ship your own source code.

Enough to  say – try it out yourself:

  1. Download the Lazarus package (already includes the compiler)
    http://www.lazarus.freepascal.org/
    http://www.freepascal.org/
  2. Start learning the language (like you would do with C#, Objective-C, Smalltalk or something else)
  3. Watch the YouTube tutorial videos
  4. Read our FreePascal/Lazarus success story :-)…

Do you need someone else to develop the application for you using FreePascal? Then don’t hesitate to ask us!

GDB/FreePascal – How a debugger can trigger on variable corruption

Problem: Some variable is overwritten in your program and you need to find the location where this will happen.

Example: As you can see from the program output, the variable ‘otherdata’ has been corrupted by the variable ‘data. Imagine, between the corruption and using again the variable ‘otherdata’ million of code lines could be executed!

program project1;
type p64 = ^int64;

procedure testme;
var
  otherdata: integer;
  data: integer;
begin
  writeln('data=',hexStr(data, 8));
  writeln('otherdata=',hexStr(otherdata, 8));
  writeln;

  p64(@data)^:=$00AABBBBCCCCDDDD;  // overwrites otherdata
  writeln('dummy');
  writeln('dummy');
  writeln('data=',hexStr(data, 8));
  writeln('otherdata=',hexStr(otherdata, 8));
end;

begin
  testme();
end.

C:Projectsfrtestdebugger>project1.exe

data=7FFDB000
otherdata=0042C294
dummy
dummy
data=CCCCDDDD
otherdata=00AABBBB


Solution:
GDB has the ability to ‘watch‘ for variable changes and trigger them! In this example, it will stop execution at the line that corrupts the OTHERDATA variable.

C:\Projects\fr\test\debugger>gdb project1.exe

GNU gdb 6.8
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type “show copying”
and “show warranty” for details.
This GDB was configured as “i686-pc-mingw32″…
(gdb)

(gdb) break TESTME
Breakpoint 1 at 0x4014ff: file project1.lpr, line 23.

Breakpoint 1, TESTME () at project1.lpr:23
23        writeln(‘data=’,hexStr(data, 8));

(gdb) watch OTHERDATA
Hardware watchpoint 2: OTHERDATA

(gdb) continue
Continuing.
data=7FFDC000
otherdata=0042C294

Hardware watchpoint 2: OTHERDATA

Old value = 4375188
New value = 11189179
TESTME () at project1.lpr:27
27        writeln(‘dummy’);

Hopefully this feature will get into Lazarus soon 😉