caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] printable digest strings
@ 2001-05-03 22:32 Miles Egan
  2001-05-04  9:15 ` Hendrik Tews
  2001-05-04  9:37 ` Xavier Leroy
  0 siblings, 2 replies; 11+ messages in thread
From: Miles Egan @ 2001-05-03 22:32 UTC (permalink / raw)
  To: caml-list

I can't seem to find a function to create printable versions of the digest
strings generated by the digest module, like the output of the common unix
md5sum utility.  Am I missing something or does it not exist?  If not, it might
be a handy addition to the Digest module.  At the moment I'm using this fairly
gross code of my own:

let hexchar nibble =
  let ac = Char.code 'a' in
  let zc = Char.code '0' in
  if nibble > 9 then
    Char.chr (nibble + ac - 10)
  else
    Char.chr (nibble + zc)

let hexstring s =
  let
    j = ref 0 and
    h = String.create (String.length s * 2) in
    for i = 0 to (String.length s - 1) do
      let
        high = ((Char.code s.[i]) lsr 4) land 0xf and
        low = (Char.code s.[i]) land 0xf in
        let _ = h.[!j] <- hexchar high in
        let _ = j := !j + 1 in
        let _ = h.[!j] <- hexchar low in
        j := !j + 1
    done;
    h

-- 
miles
-------------------
To unsubscribe, mail caml-list-request@inria.fr.  Archives: http://caml.inria.fr


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] printable digest strings
  2001-05-03 22:32 [Caml-list] printable digest strings Miles Egan
@ 2001-05-04  9:15 ` Hendrik Tews
  2001-05-04  9:37 ` Xavier Leroy
  1 sibling, 0 replies; 11+ messages in thread
From: Hendrik Tews @ 2001-05-04  9:15 UTC (permalink / raw)
  To: Miles Egan; +Cc: caml-list

Hi,

Miles Egan writes:
   From: Miles Egan <miles@caddr.com>
   Date: Thu, 3 May 2001 15:32:34 -0700
   Subject: [Caml-list] printable digest strings
   
   I can't seem to find a function to create printable versions
   of the digest strings generated by the digest module, like the
   output of the common unix md5sum utility. Am I missing
   something or does it not exist? 

What about String.escaped?

>From the string module docs:

val escaped: string -> string

     Return a copy of the argument, with special characters
     represented by escape sequences, following the lexical
     conventions of Objective Caml.

Bye,

Hendrik
-------------------
To unsubscribe, mail caml-list-request@inria.fr.  Archives: http://caml.inria.fr


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] printable digest strings
  2001-05-03 22:32 [Caml-list] printable digest strings Miles Egan
  2001-05-04  9:15 ` Hendrik Tews
@ 2001-05-04  9:37 ` Xavier Leroy
  2001-05-04 14:00   ` Miles Egan
  2001-05-04 20:27   ` Chris Hecker
  1 sibling, 2 replies; 11+ messages in thread
From: Xavier Leroy @ 2001-05-04  9:37 UTC (permalink / raw)
  To: Miles Egan; +Cc: caml-list

> I can't seem to find a function to create printable versions of the
> digest strings generated by the digest module, like the output of
> the common unix md5sum utility.  Am I missing something or does it
> not exist?

It does not exist, but as you said it could be handy.

> If not, it might be a handy addition to the Digest
> module.  At the moment I'm using this fairly gross code of my own:

You can use Printf.sprintf "%02x" to convert each byte to hexadecimal
in a more concise way.  E.g.:

let string_map f s =            
  let rec map_aux res idx =
    if idx < 0 then res else map_aux (f s.[idx] :: res) (idx - 1)  
  in map_aux [] (String.length s - 1)

let hexstring s =
  String.concat "" 
    (string_map (fun c -> Printf.sprintf "%02x" (Char.code c)) s)

Or in a more imperative style (real programmers don't build
intermediate lists :-)

let hexstring s =
  let res = String.create (String.length s * 2) in
  for i = 0 to String.length s - 1 do
    String.blit (Printf.sprintf "%02x" (Char.code s.[i])) 0
                res (2 * i) 2
  done;
  res

Hope this helps,

- Xavier Leroy
-------------------
To unsubscribe, mail caml-list-request@inria.fr.  Archives: http://caml.inria.fr


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] printable digest strings
  2001-05-04  9:37 ` Xavier Leroy
@ 2001-05-04 14:00   ` Miles Egan
  2001-05-04 14:50     ` Brian Rogoff
  2001-05-04 20:27   ` Chris Hecker
  1 sibling, 1 reply; 11+ messages in thread
From: Miles Egan @ 2001-05-04 14:00 UTC (permalink / raw)
  To: caml-list

On Fri, May 04, 2001 at 11:37:27AM +0200, Xavier Leroy wrote:
> let string_map f s =            
>   let rec map_aux res idx =
>     if idx < 0 then res else map_aux (f s.[idx] :: res) (idx - 1)  
>   in map_aux [] (String.length s - 1)
> 
> let hexstring s =
>   String.concat "" 
>     (string_map (fun c -> Printf.sprintf "%02x" (Char.code c)) s)

I knew there had to be a better way.  Thanks.

This actually brings me to my next question.  There doesn't seem to be a
String.map or String.iter function in the standard library, although I can
imagine they might also be handy.  Am I looking in the wrong place?

-- 
miles
-------------------
To unsubscribe, mail caml-list-request@inria.fr.  Archives: http://caml.inria.fr


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] printable digest strings
  2001-05-04 14:00   ` Miles Egan
@ 2001-05-04 14:50     ` Brian Rogoff
  0 siblings, 0 replies; 11+ messages in thread
From: Brian Rogoff @ 2001-05-04 14:50 UTC (permalink / raw)
  To: Miles Egan; +Cc: caml-list

On Fri, 4 May 2001, Miles Egan wrote:
> This actually brings me to my next question.  There doesn't seem to be a
> String.map or String.iter function in the standard library, although I can
> imagine they might also be handy.  Am I looking in the wrong place?

Nope, they're not there. You could use the compiler source, and steal the
corresponding functions from arrays, since OCaml does the right thing and 
has array-like strings (as opposed to say, Erlang and Haskell). Here's the 
touch up for those two

let iter f s =
  for i = 0 to String.length s - 1 do f(String.unsafe_get s i) done

let map f s =
  let l = String.length s in
  if l = 0 then "" else begin
    let r = String.create l in
    for i = 1 to l - 1 do
      String.unsafe_set r i (f(String.unsafe_get s i))
    done;
    r
  end

You can now (OCaml 3.01) make your own String module with these functions
and include the native String module to get what you want. 

This is another one of those cases where some overloading might be nice,
since IMO there is not much point in distinguishing all of the different 
kinds of random access with .[], .(), .{}. 

-- Brian


-------------------
To unsubscribe, mail caml-list-request@inria.fr.  Archives: http://caml.inria.fr


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] printable digest strings
  2001-05-04  9:37 ` Xavier Leroy
  2001-05-04 14:00   ` Miles Egan
@ 2001-05-04 20:27   ` Chris Hecker
  2001-05-04 22:54     ` Miles Egan
  2001-05-06 18:56     ` [Caml-list] Wserver: Values of global variables lost Mattias Waldau
  1 sibling, 2 replies; 11+ messages in thread
From: Chris Hecker @ 2001-05-04 20:27 UTC (permalink / raw)
  To: Xavier Leroy, Miles Egan; +Cc: caml-list


>Or in a more imperative style (real programmers don't build
>intermediate lists :-)

Real programmers prematurely optimize silly little functions (code below) and don't call sprintf per character:

:)

native code

test    secs
----    ----
hex     0.38
hexu    0.16
hexx    7.30

bytecode

test    secs
----    ----
hex      2.75
hexu     2.31
hexx    27.24


> string_map

On a more serious note/question, you define string_map as:

string_map : (char -> 'a) -> string -> 'a list

Since I'm still trying to grok this functional thing, I guess there's really no other way to do it (except maybe 'a array) because the function could expand its char into another type, right?  In other words, other maps are 

map: ('a -> 'b) -> 'a type -> 'b type

so there's a certain amount of symmetry.  Since string is a builtin, there's no way to have a "float string" or whatever if your function is char -> float.  Is 'a array the right thing to return here, or 'a list?  Or is this a stupid irrelevant question?

Chris

PS.  It's pretty clear from looking at the asm output of hexu that languages with shifted-up ints sure could benefit from crazy shift-mask instructions like the PPC has.  The x86 just dies on this sort of thing with no ternary instructions and no good shift-mask ops.


--- test harness ---
let _ =
  let s = String.make 10000 'g' in
  let r = ref "" in
  for i = 0 to 100 do
    r := hexstring s;
  done


---- hex ----
let hexstring s =
  let res = String.create (String.length s * 2) in
  let hex = "0123456789abcdef" in
  for i = 0 to String.length s - 1 do
    let c = Char.code s.[i] in
    res.[2*i] <- hex.[c lsr 4]; res.[2*i+1] <- hex.[c land 15]
  done;
  res

---- hexu ----
let hexstring s =
  let res = String.create (String.length s * 2) in
  let hex = "0123456789abcdef" in
  for i = 0 to String.length s - 1 do
    let c = Char.code (String.unsafe_get s i) in
    String.unsafe_set res (2*i)   (String.unsafe_get hex (c lsr 4));
    String.unsafe_set res (2*i+1) (String.unsafe_get hex (c land 15));
  done;
  res

---- hexx ----

let hexstring s =
  let res = String.create (String.length s * 2) in
  for i = 0 to String.length s - 1 do
    String.blit (Printf.sprintf "%02x" (Char.code s.[i])) 0
                res (2 * i) 2
  done;
  res


-------------------
To unsubscribe, mail caml-list-request@inria.fr.  Archives: http://caml.inria.fr


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] printable digest strings
  2001-05-04 20:27   ` Chris Hecker
@ 2001-05-04 22:54     ` Miles Egan
  2001-05-06 18:56     ` [Caml-list] Wserver: Values of global variables lost Mattias Waldau
  1 sibling, 0 replies; 11+ messages in thread
From: Miles Egan @ 2001-05-04 22:54 UTC (permalink / raw)
  To: Chris Hecker; +Cc: caml-list

On Fri, May 04, 2001 at 01:27:36PM -0700, Chris Hecker wrote:
> map: ('a -> 'b) -> 'a type -> 'b type
> 
> so there's a certain amount of symmetry.  Since string is a builtin, there's no way to have a "float string" or whatever if your function is char -> float.  Is 'a array the right thing to return here, or 'a list?  Or is this a stupid irrelevant question?
> 

Well, list map is:
map : f:('a -> 'b) -> 'a list -> 'b list

So it's more of a 'a sequence -> 'b sequence function.

I don't think I've really gotten the hang of string manipulation in ocaml yet.

-- 
miles
-------------------
To unsubscribe, mail caml-list-request@inria.fr.  Archives: http://caml.inria.fr


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Caml-list] Wserver: Values of global variables lost
  2001-05-04 20:27   ` Chris Hecker
  2001-05-04 22:54     ` Miles Egan
@ 2001-05-06 18:56     ` Mattias Waldau
  2001-05-07  8:58       ` Daniel de Rauglaudre
  2001-05-07 17:00       ` Mattias Waldau
  1 sibling, 2 replies; 11+ messages in thread
From: Mattias Waldau @ 2001-05-06 18:56 UTC (permalink / raw)
  To: caml-list

I am trying to use wserver, and create a simple ocaml-based webserver.

I am using it locally, and I assumed that the global variables in my ocaml 
would be kept during the interaction with the user.

However, in the following program sofar is always ref "".

What have I misunderstood? How should I do? Have anyone else implemented a
minimal www-server?

My program that is compiled together with wserver, unix.cma and str.cma.
I use ocaml 3.01 on Redhat 7.1

/mattias

(* let _ = Wserver.f 2368 60 (fun _ s -> Printf.printf "You said: %s...\n" s) 
*)

let sofar = ref ""

let _ =
  let socket = 
    if Array.length Sys.argv > 1 then int_of_string Sys.argv.(1) else 2368 in
  Printf.printf "\nListening on socket %d\n" socket;
  flush stdout;
  Wserver.f socket 60 
    (fun _ s -> 
      Printf.printf "You said: %s...(%s)\n" 
	(Wserver.decode s)(Wserver.decode !sofar);
      sofar := !sofar ^ ", " ^ s;
      prerr_string !sofar; prerr_newline ()
    )

-------------------
To unsubscribe, mail caml-list-request@inria.fr.  Archives: http://caml.inria.fr


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] Wserver: Values of global variables lost
  2001-05-06 18:56     ` [Caml-list] Wserver: Values of global variables lost Mattias Waldau
@ 2001-05-07  8:58       ` Daniel de Rauglaudre
  2001-05-07 17:00       ` Mattias Waldau
  1 sibling, 0 replies; 11+ messages in thread
From: Daniel de Rauglaudre @ 2001-05-07  8:58 UTC (permalink / raw)
  To: Mattias Waldau; +Cc: caml-list

Hi,

On Sun, May 06, 2001 at 08:56:48PM +0200, Mattias Waldau wrote:

> I am trying to use wserver, and create a simple ocaml-based webserver.
> 
> I am using it locally, and I assumed that the global variables in my ocaml 
> would be kept during the interaction with the user.
> 
> However, in the following program sofar is always ref "".

It is because a new process is launched at every request. Wserver uses
the Unix.fork function which creates a separated process, the global
variables are therefore not shared.

It would have worked if Wserver had used the threads but it it not
implemented like that.

-- 
Daniel de RAUGLAUDRE
daniel.de_rauglaudre@inria.fr
http://cristal.inria.fr/~ddr/
-------------------
To unsubscribe, mail caml-list-request@inria.fr.  Archives: http://caml.inria.fr


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] Wserver: Values of global variables lost
  2001-05-06 18:56     ` [Caml-list] Wserver: Values of global variables lost Mattias Waldau
  2001-05-07  8:58       ` Daniel de Rauglaudre
@ 2001-05-07 17:00       ` Mattias Waldau
  2001-05-07 18:16         ` Daniel de Rauglaudre
  1 sibling, 1 reply; 11+ messages in thread
From: Mattias Waldau @ 2001-05-07 17:00 UTC (permalink / raw)
  To: caml-list

The problem was the fork.

I solved the problem by taking the wserver included in geneweb, and 
recompiling it with -DNOFORK. 

Now everything works as expected.

/mattias
-------------------
To unsubscribe, mail caml-list-request@inria.fr.  Archives: http://caml.inria.fr


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] Wserver: Values of global variables lost
  2001-05-07 17:00       ` Mattias Waldau
@ 2001-05-07 18:16         ` Daniel de Rauglaudre
  0 siblings, 0 replies; 11+ messages in thread
From: Daniel de Rauglaudre @ 2001-05-07 18:16 UTC (permalink / raw)
  To: Mattias Waldau; +Cc: caml-list

Hi,

On Mon, May 07, 2001 at 07:00:01PM +0200, Mattias Waldau wrote:

> I solved the problem by taking the wserver included in geneweb, and 
> recompiling it with -DNOFORK. 

Indeed, but now, you must pay attention that your function does not
generate memory leaks: think of closing your opened channels, things
like that. You must program clean what is not necessary with the fork
version.

But with this option NOFORK, Wserver is nice with you: if there have
been no requests since the last 15 seconds, a Gc.compact is triggered.

-- 
Daniel de RAUGLAUDRE
daniel.de_rauglaudre@inria.fr
http://cristal.inria.fr/~ddr/
-------------------
To unsubscribe, mail caml-list-request@inria.fr.  Archives: http://caml.inria.fr


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2001-05-07 18:16 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-05-03 22:32 [Caml-list] printable digest strings Miles Egan
2001-05-04  9:15 ` Hendrik Tews
2001-05-04  9:37 ` Xavier Leroy
2001-05-04 14:00   ` Miles Egan
2001-05-04 14:50     ` Brian Rogoff
2001-05-04 20:27   ` Chris Hecker
2001-05-04 22:54     ` Miles Egan
2001-05-06 18:56     ` [Caml-list] Wserver: Values of global variables lost Mattias Waldau
2001-05-07  8:58       ` Daniel de Rauglaudre
2001-05-07 17:00       ` Mattias Waldau
2001-05-07 18:16         ` Daniel de Rauglaudre

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).