als RSS-Feed abonnieren
Hundezuechter
McKinsey
XML-Ferientermine
xml-ferientermine
Go-Spiel-bei-DGS
Projektarbeit
Wohnungssuche
Bewerbungen
Ruby-in-Second-Life
Clatronic-CTV731-bei-Saturn
T_Shirts_Mousepads
Singleboersenvergleich
TimeSystem
Katzen
katzen
Arbeitsamt_I
Klick
2007-01-21
2007-01-19
Leapc
iMacros-to-Watir-Konverter
ASP
Ruby-Stocks
National-Geograpic
Google-Kalender
XML-Ruby
XMLTV
css
scribus
ruby-links
c-sharp
videos-fuer-psp-konvertieren
tchibo-infoglobe
uuencode-ruby
linux-phone-neo-1973
mx600-mouse
ruby-mechanize-https
ncurses
internetcafes
corba
ruby-einladung
ruby-setup
ruby-xml
watir
find-ersatz-in-ruby
ruby-priority-queue
gem-needle
gem-dependency
index
DotNetTests
TDD
Gadgets
RSS
Geocaching
2006-10-22_CSS_hier
2006-10-22-zaurus
2006-10-22
2006-10-22_Mono_und_Linux


vom: 2006-11-21 21:48

UUencode in Ruby

Weil sich die Konvertierung mittels Ruby in uuencodete Dateien irgendwie anders verhielt als das Original-uuencode Programm unter Linux verhielt, habe ich mich daran gemacht, das uuencode-Programm nach Ruby zu portieren.

Ein anderer Grund war, daß uudecode auf einigen Linux-Distributionen anscheinend nicht standardmäßig installiert ist und auch per ‘yum update uudecode’ anscheinend auch nicht gefunden wird (wenn jemand für letzteres eine Lösung weiß, bitte per Mail mitteilen!). Ich hätte mir natürlich auch die C-Source dafür irgendwo besorgen können, aber ich wollte das dann doch lieber in Ruby lösen.

Hier meine Lösung:

Hierbei ist anzumerken, daß die uuencode-Programm unter Unix/Linux auch nach dem base64-Verfahren kodieren können – dies habe ich in meinem Programm vorerst noch nicht implementiert.

Als erstes das Skript, das die Unit-Tests ausführt, um die Funktionen meines neuen Programms zu testen.

require 'test/unit' unless defined? $ZENTEST and $ZENTEST
require 'uuencode'
require 'profile'

class TestUUencode < Test::Unit::TestCase
  def setup
    @uu = UUencode.new("main")
  end

  def test_encode
    uuencoded = `uuencode #{@uu.name} #{@uu.name}.uue`
    # puts uuencoded
    f=File.open("#{@uu.name}.uue.1","w")
    f.puts(uuencoded)
    f.close
    # uuendcode muss gleich sein mit unserer Ausgabe
    f=File.open("#{@uu.name}.uue.2","w")
    f.puts(@uu.encode)
    f.close
    assert_equal(uuencoded,@uu.encode)
  end

  def test_mache_viele_programme
    1.upto(20) do |n|
      source=<<END
      int main (int argc, char argv[])
      {
        int i;
        for (i=1;i<#{n};i++) {
          printf("hallo\\n");
        }
        return 42;
      }
END
      `echo '#{source}' >main.c`
      `make main`
      uuencoded = `uuencode #{@uu.name} #{@uu.name}.uue`
      f=File.open("#{@uu.name}.uue.1","w")
      f.puts(uuencoded)
      f.close
      # uuendcode muss gleich sein mit unserer Ausgabe
      f=File.open("#{@uu.name}.uue.2","w")
      f.puts(@uu.encode)
      f.close
      assert_equal(uuencoded,@uu.encode)
    end
  end
end

Zu den Test ist nicht viel zu sagen – ein Test dient dazu, die Ergebnisse des originalen uuencode-Programms unter Linux und meines Programmms zu vergleichen, um zu testen, ob beide das gleiche Ergebnis liefern. Bei dem Programm ‘main’ handelt es sich um ein einfaches Hello-World-Programm.

Bei dem zweiten Test werden innerhalb des Testprogramm mehrere C-Sourcecodes erzeugt, kompiliert und wiederum die Ergebnisse des Linux-uuencode-Programms und meines Programm miteinander verglichen – wenn beide Ergebnisse identisch sind, wird mein Programm wohl korrekt funktionieren.

Hier nun meine eigentliches Programm:

#!/bin/env ruby
class UUencode

  attr_reader :name

  def initialize(name)
    @name = name
  end

  def to_s
    puts "none" 
  end

  def encode
    result = "begin 775 #{@name}.uue\n" 
    line = "" 
    whole_file="" 
    f=File.open("#{@name}") do |file|
      whole_file = file.read
    end
    pos = 0
    b=[]
    s=[]
    bytes_in_line = 0
    while pos < whole_file.length
      0.upto(2) {|i|
        if pos+i < whole_file.length
          b[i] = whole_file[pos+i,1][0]
          bytes_in_line += 1
        else
          b[i] = 0
        end
        s[i]=sprintf("%08d",b[i].to_s(2))
      }
      zusammen = s.to_s
      0.upto(3) do |i|
        s[i]=zusammen[i*6,6]
        c = (s[i].to_i(2) + " "[0]).chr
        c = '`' if c==' '
        line << c
      end
      pos += 3

      if bytes_in_line >= 45
        count = (bytes_in_line+32).chr
        result << count+line+"\n" 
        bytes_in_line = 0
        line = "" 
      end
    end
    count = (bytes_in_line+32).chr
    count = '`' if count==' '
    result << count+line+"\n" 
    result << "end\n" 
    result
  end

end # class

Kontakt: Thomas Preymesser
Prinzenallee 36
13359 Berlin
Telefon: 030 - 49 78 37 06
mobile: 0172-8111959
eMail: thopre@gmail.com