UUE кодирование файлов

С момента одного из моих постов, несколько человек попросили показать пример утилитки (или исходника на Icon), так вот сейчас по заявкам граждан я покажу свою утилитку для кодирования файлов в UUE.

Зачем нужно такое кодирование ?

Ну, я — фидошник, и иногда мне приходиться отсылать файлы с помощью Фидонета, а как известно, многие узлы не пропускают через себя письма со вложенными в них файлами, и поэтому была изобретена такая хитрость: файл кодируется с помощью UUE-кодера и результат кодирования вставляется прямо в письмо. Здесь фишка в том, что результат UUE-кодирования состоит только из печатных символов, а именно это и необходимо для вставки файла в письмо.

В общем, написание программы кодирования в UUE-формат стало одним из первых моих серьезных экспериментов (поэтому собственно прошу программистов не пинать сильно) — и наглядно показало мне возможности Icon.

Ну, а теперь, по просьбам трудящихся, я вставляю сюда код утилитки:

 procedure main(argv)
 local f,o,r,r2

# получаем первый аргумент (имя входного файла) и если оно не задано 
# возвращаем ошибку
# также инициализируем строку-накопитель f

 r:=argv[1]
 if /r then stop("no 1th argument!") 
 f:="" 

# получаем второй аргумент (имя выходного файла) и если оно не задано
# то берем текущую дату в качестве имени, а в качестве расширения 
# ставим .uue (проводим преобразование строки с датой,заменяя в ней
# все символы / на _)

 r2:=argv[2]
 if /r2 then r2:=map(string(&date)||".uue","/","_")

# открытие входного и выходного файла

 g:=open(r,"ru")
 t:=open(r2,"cw")

# запись первой строки uue

 z:="begin 644 uue"||r[((*r)-3)+:4]
 write(t,z)

# запускаем процедуру преобразования в uue
# если строка f содержит 60 символов,то записываем
# ее с символом М впереди
# иначе записываем эту строку с другим символом,
# отражающим ее размер

 while f:=f||(|rd(g)) do {
        if *f=60 then {
                write(t,"M"||f)
                f:="" 
        }
 }
 if (*f~=0)&(*f<60) then {
        o:=(((*f)*6)/8)+32
        write(t,char(o)||f)
 }

# запись конечной строки и символа защиты от повреждения

 write(t,"`\n","end")
 end

# перевод в двоичную систему,8-битный формат

 procedure to_bin(x)
 local r,s,n
 n:=x
 s:="" 
 while n>=1 do {
 r:=n%2
 s:=s||r
 n:=integer(n/2)
 }
 s:=reverse(s)
 while *s~=8 do {
  s:="0"||s    
 }
 return string(s)
 end

# перевод двоичного числа в десятичное

 procedure to_dec(d)
 local b,i,v
 b:=0
 v:=reverse(d)
 every i:=1 to *d do {
  b:=b+((2^(i-1))*v[i])
 }
 return b
 end

# преобразование трех байт в четверку из 6 битов
# и интерпретация их как символов ASCII

 procedure rd(g)
 local s,d,t,a1,a2,a3,a4,v
 d:="" 
 v:="" 
 while s:=reads(g,3) do {
 every t:=1 to *s do {
 d:=d||to_bin(ord(s[t]))       
 }
 while *d~=24 do {
 d:=d||"0"     
 }
 a1:=char(to_dec(d[1+:6])+32)
 a2:=char(to_dec(d[7+:6])+32)
 a3:=char(to_dec(d[13+:6])+32)
 a4:=char(to_dec(d[19+:6])+32)
 v:=a1||a2||a3||a4
 return v
 }
 end

Сохраняем все это в файл uue.icn (*.icn — расширение файлов с исходными кодами программ на Icon) и, по возможности, правим (лучше всего в jEdit, т.к как у него есть подсветка синтаксиса Icon) и затем запускаем на выполнение:

icont uue.icn -x входной_файл [выходной файл]

(в квадратных скобках я указал необязательный параметр, т.е если путь к выходному файлу задан не будет, то в текущей директории после работы программы появится файла вида год_месяц_число.uue)

Пример вывода программы  (UUE):

begin 644 50px-Yozh.jpg
M_]C_X  02D9)1@ ! 0$ 2 !(  #_VP!#  8$!08%! 8&!08'!P8("A *"@D)
M"A0.#PP0%Q08&!<4%A8:'24?&ALC'!86("P@(R8G*2HI&1\M,"TH,"4H*2C_
MVP!# 0<'!PH("A,*"A,H&A8:*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H
M*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"C_P  1"  P #(# 2(  A$! Q$!_\0 
M&P   @(# 0              !P@ !@,$!0+_Q  T$  " 0,# @4# 08'    
M   ! @,$!1$ !B$2,0<405%A$R)Q%18C,D*Q\"5#4I'!T=+_Q  8 0$! 0$!
M               # @ !!/_$ " 1  (" @(" P             ! A$#$B$B
M!#%1<!--?'_V@ , P$  A$#$0 _ &F=U098@:X-VW%24.5ED1<+G+, &^!\ZK?B
M-O%;'2]'TY&F;A#%R0?<@GM^,Z6S>7B#7UUWC217F/9PA^T#V..!CG.<'4.5
M&Y?H8.L\1,I(\$$C,O"@KP?N SKA5WBG/;9UCJ+<71FZB5;&>!S_ +_\:%MK
MW%1[EIY(KK*]*J2!8X8'^F2F/XF(&>P[#WYQQK1W!;_-;NCH;54%4E50.78Q
MH3@ <'DY[^N?P-2VZMG$FW0?=L>+-HNM0\,A\LX/^<PP3@=O3OHE459'51*\
M7*GL??YTKF^/"^@ME@JJRVU0CKH(O,1Q))DN5P&SD\CDG/!_IKM^ .]:^KD_
M3:Z;K58@ZDGJ*<\@G^_;6QY%/E%RCJ,CU#WU-:\<O7&K#&" >^II20!>.MEK
MC4P55&*FH8LQ$8!8)\C!XX&JE^@TD-PM,2T42QU5$)JTA<^7'))?D=\GYPGP
M=,AOV:DHMI72JK@3!%3NS '&<C SCY(T'/V>2*T4%SN]_FJZN40]<3.LR5)B
M4X5<!23CJP#G.?7&O)Y%77R+A37($?$/:K[7W!_@\[3P53<*BEV0]\#&>XYX
M]-9*-JVH6&[VMEDKH"#(ZR<)TC@$-[GT&BM=KQ16^[Q7:UTE374+1+61*D&5
MB2(!#P%'2 & SS\Z$:N-N[UJ/)U"36RM;S5))EOOC<DJ2 <9!)4CT*ZG#)N.
MLOT[F5=D$/:K7+?]-N*GW$\<0>C$D$Z95X2F3U=1Y*GL5S@\XU5O!>I:"_4;
MGK,C.&.#QR?8?W[ZL'Z"*JIJ#3U%0L59&%E,3LZR+CL<=/';MGMC7O9VVJC;
M^\H5C'52*X Z#CJ]!G)QG/\ 32QZ_0$I70R:U,P4#ZB=O]1_\ZFLD4DAB0]4
M@R!QGMJ:<Z:?B()*C:%[I@2C&D=U9#U,O2,@XQ[CMH4;CGN%YAH*ZQ7-(I[7 M]&+S1A >8U#!>E6' &.>.>>XTP,B*RD,H((P01G(TO\ 7[$W38[3>Z2AH;>U
M*]6KT3P.Y=AYA9$+J >E8U#+P/YCZ:')CVENGZ$C.E1BO]FW'7VRZ6EKQ'!3
MTL30#^)4F=XU+*_\S#[L99F/&?R&4ML&TK8:#?$JUSR=4U'0T;!Y87/:7ZO'
M0K$?P_=U=\<9T6]Z6?-->-TEG.W(9X+K5B))(DPP7  ,AE*X7V ZAP!W.JI%X#
M;WN-9YJ]54;5;J"[RR_4)QP!GOG&-1B4Y<R9ITE2,NSKM#:[%'+5N1,8QU+* MZA6]?;.,?C5AV@U7>MPQ"'Z;?<"70'."<Y^1^-<]_ O=9:,"Z4YA4 $!""I^
M =&;P[V+^SM*OF_WT[*.IF /Y&EU;8"3+E%"5C16+D@ $\_]ZFMX)@:FDHL_
"_]D 
 
end

Вот собственно и все :)

UPD: К сожалению, я больше уже не фидошник :(

Добавить комментарий