<commit_before>(*
 * Copyright (C) 2006-2009 Citrix Systems Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation; version 2.1 only. with the special
 * exception on linking described in file LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *)

open Printf
open Rpc

let debug = ref false
let debug (fmt: ('a, unit, string, unit) format4) : 'a =
	kprintf (fun s -> if !debug then begin print_string s; print_newline (); flush stdout end) fmt

(* marshalling/unmarshalling code *)

(* The XML-RPC is not very clear about what characters can be in a string value ... *)
let encode s =
	let n = String.length s in
	let aux = function
		| '>'    -> Some "&gt;"
		| '<'    -> Some "&lt;"
		| '&'    -> Some "&amp;"
		| '"'    -> Some "&quot;"
		| c when (c >= '\x20' && c <= '\xff') || c = '\x09' || c = '\x0a' || c = '\x0d'
		         -> None
		| _      -> Some "" in
	let need_encoding =
		let b = ref false in
		let i = ref 0 in
		while not !b && !i < n-1 do
			b := aux s.[ !i ] <> None;
			incr i;
		done;
		!b in
	if need_encoding then begin
		let buf = Buffer.create 0 in
		let m = ref 0 in
		for i = 0 to n-1 do
			match aux s.[i] with
			| None   -> ()
			| Some n ->
				  Buffer.add_substring buf s !m (i - !m);
				  Buffer.add_string buf n;
				  m := i + 1
		done;
		Buffer.add_substring buf s !m (n - !m);
		Buffer.contents buf
	end else
		s

let rec add_value f = function
	| Null ->
		f "<value><nil/></value>"

	| Int i  ->
		f "<value>";
		f (Int64.to_string i);
		f "</value>"

	| Bool b ->
		f "<value><boolean>";
		f (if b then "1" else "0");
		f "</boolean></value>"

	| Float d ->
		f "<value><double>";
		f (Printf.sprintf "%g" d);
		f "</double></value>"

	| String s ->
		f "<value>";
		f (encode s);<commit_msg>[rpc-light]: when marshalling XMLRPC, don't lose float precision<commit_after>(*
 * Copyright (C) 2006-2009 Citrix Systems Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation; version 2.1 only. with the special
 * exception on linking described in file LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *)

open Printf
open Rpc

let debug = ref false
let debug (fmt: ('a, unit, string, unit) format4) : 'a =
	kprintf (fun s -> if !debug then begin print_string s; print_newline (); flush stdout end) fmt

(* marshalling/unmarshalling code *)

(* The XML-RPC is not very clear about what characters can be in a string value ... *)
let encode s =
	let n = String.length s in
	let aux = function
		| '>'    -> Some "&gt;"
		| '<'    -> Some "&lt;"
		| '&'    -> Some "&amp;"
		| '"'    -> Some "&quot;"
		| c when (c >= '\x20' && c <= '\xff') || c = '\x09' || c = '\x0a' || c = '\x0d'
		         -> None
		| _      -> Some "" in
	let need_encoding =
		let b = ref false in
		let i = ref 0 in
		while not !b && !i < n-1 do
			b := aux s.[ !i ] <> None;
			incr i;
		done;
		!b in
	if need_encoding then begin
		let buf = Buffer.create 0 in
		let m = ref 0 in
		for i = 0 to n-1 do
			match aux s.[i] with
			| None   -> ()
			| Some n ->
				  Buffer.add_substring buf s !m (i - !m);
				  Buffer.add_string buf n;
				  m := i + 1
		done;
		Buffer.add_substring buf s !m (n - !m);
		Buffer.contents buf
	end else
		s

let rec add_value f = function
	| Null ->
		f "<value><nil/></value>"

	| Int i  ->
		f "<value>";
		f (Int64.to_string i);
		f "</value>"

	| Bool b ->
		f "<value><boolean>";
		f (if b then "1" else "0");
		f "</boolean></value>"

	| Float d ->
		f "<value><double>";
		(* NB: "%g" loses a lot of precision (e.g. resulting in "1.32621e+09") *)
		f (Printf.sprintf "%0.16g" d);
		f "</double></value>"

	| String s ->
		f "<value>";
		f (encode s);
{'fraction_non_alphanumeric': 0.14511260738332946, 'fraction_numerical': 0.015556071511492919, 'mean_word_length': 2.5780730897009967, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 65, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4511223', 'n_tokens_mistral': 1619, 'n_tokens_neox': 1455, 'n_words': 609}