open Printf let iterations = 100;; (*============================================================================*) let get_byte str off = (*1*) int_of_char(str.[off]);; (*2*) let get_duo str off = (*3*) ((int_of_char (str.[off])) lsl 8) lor (*4*) (int_of_char (str.[off+1]));; (*5*) let get_triplet str off = (*6*) ((int_of_char (str.[off])) lsl 16) lor (*7*) ((int_of_char (str.[off+1])) lsl 8) lor (*8*) (int_of_char (str.[off+2]));; (*9*) let uu_encode_byte byteval string init_offset = (*10*) (string.[init_offset] <- char_of_int(((byteval lsr 2) land 63)+32); (*11*) string.[init_offset+1] <- char_of_int(((byteval lsl 4) land 63)+32); (*12*) string.[init_offset+2] <- char_of_int 61; (*13*) string.[init_offset+3] <- char_of_int 61);; (*14*) let uu_encode_duo duo string init_offset = (*15*) (string.[init_offset] <- char_of_int(((duo lsr 10) land 63)+32); (*16*) string.[init_offset+1] <- char_of_int(((duo lsr 4) land 63)+32); (*17*) string.[init_offset+2] <- char_of_int(((duo lsl 2) land 63)+32); (*18*) string.[init_offset+3] <- char_of_int 61);; (*19*) let uu_encode_triplet triplet string init_offset = (*20*) (string.[init_offset] <- char_of_int(((triplet lsr 18) land 63)+32); (*21*) string.[init_offset+1] <- char_of_int(((triplet lsr 12) land 63)+32); (*22*) string.[init_offset+2] <- char_of_int(((triplet lsr 6) land 63)+32); (*23*) string.[init_offset+3] <- char_of_int((triplet land 63)+32));; (*24*) let preamble fname access = (*25*) let u = char_of_int((access lsr 6) + 48) (*26*) and g = char_of_int(((access lsr 3) land 7) + 48) (*27*) and a = char_of_int((access land 7) + 48) (*28*) in let astring = String.create 4 in (*29*) (astring.[0] <- u; astring.[1] <- g; astring.[2] <- a; (*30*) astring.[3] <- char_of_int 32); (*31*) let prefix = "begin " ^ astring ^ fname ^ " \n" (*32*) in prefix;; (*33*) let rec put_uu_line0 str offset limit res resind = (*34*) if offset= 3 (*49*) then (uu_encode_triplet (get_triplet str offset) res resind; (*50*) put_last_line0 str (offset+3) limit res (resind+4)) (*51*) else if rembytes == 0 (*52*) then res (*53*) else if rembytes == 1 (*54*) then (uu_encode_byte (get_byte str offset) res resind; res) (*55*) else (uu_encode_duo (get_duo str offset) res resind; res);; (*56*) let put_last_line str offset rembytes = (*57*) let ssize = ((need_uu_bytes rembytes)+2) (*58*) in let s = String.create ssize (*59*) in (s.[0] <- char_of_int (rembytes+32) ; (*60*) s.[ssize-1] <- char_of_int 10; (*61*) put_last_line0 str offset (offset+rembytes) s 1) ;; (*62*) let rec do_encode str offset acc = (*63*) let rem_bytes = ((String.length str) - offset) (*64*) in if rem_bytes >= 45 (*65*) then do_encode str (offset+45) ((put_uu_line str offset)::acc) (*66*) else ((put_last_line str offset rem_bytes)::acc);; (*67*) let uuencode fname str access = (*68*) let res = " \nend"::(do_encode str 0 [(preamble fname access)]) (*69*) in String.concat "" (List.rev res);; (*70*) (*============================================================================*) let get_file fname = let handle = open_in fname in let len = (in_channel_length handle); in let s = String.create len in (really_input handle s 0 len; s);; let rec iter n f = if n>1 then (f(); iter (n-1) f) else f();; let main inname outname = let str = get_file inname in let start = Sys.time() in let res = (iter iterations (function () -> uuencode inname str 0o640)) in let stop = Sys.time () in let outfile = open_out outname in let time = (stop -. start) in (output outfile res 0 (String.length res); printf "%.3f" time; flush stdout) ;; let () = let w = (Array.get Sys.argv 1) in let x = w ^ ".ocaml" in main w x;;