diff options
-rw-r--r-- | rand.c | 41 | ||||
-rw-r--r-- | rand.h | 1 | ||||
-rw-r--r-- | stdlib/doc-syms.tl | 1 | ||||
-rw-r--r-- | txr.1 | 24 |
4 files changed, 67 insertions, 0 deletions
@@ -43,6 +43,8 @@ #include "time.h" #include "buf.h" #include "txr.h" +#include "buf.h" +#include "itypes.h" #include "rand.h" #define random_warmup (deref(lookup_var_l(nil, random_warmup_s))) @@ -404,6 +406,44 @@ val rnd(val modulus, val state) return random(state, modulus); } +val random_buf(val size, val state) +{ + val self = lit("random-buf"); + struct rand_state *r = coerce(struct rand_state *, + cobj_handle(self, + default_arg(state, random_state), + random_state_cls)); + size_t sz = c_size(size, self); + mem_t *data = chk_malloc(sz); + val buf = make_owned_buf(size, data); + + for (; sz >= 4; sz -= 4, data += 4) { + rand32_t rnd = rand32(r); +#if HAVE_LITTLE_ENDIAN + *(rand32_t *) data = rnd; +#else + rnd = (0xFF00FF00U & rnd) >> 8 | (0x00FF00FFU & rnd) << 8; + *(rand32_t *) data = (rnd << 16 | rnd >> 16); +#endif + } + + if (sz > 0) { + rand32_t rnd = rand32(r); + switch (sz % 4) { + case 3: + data[2] = rnd >> 16; + /* fallthrough */ + case 2: + data[1] = rnd >> 8; + /* fallthrough */ + case 1: + data[0] = rnd; + } + } + + return buf; +} + void rand_compat_fixup(int compat_ver) { if (compat_ver <= 243) { @@ -438,4 +478,5 @@ void rand_init(void) reg_fun(intern(lit("random-float"), user_package), func_n1o(random_float, 0)); reg_fun(intern(lit("random"), user_package), func_n2(random)); reg_fun(intern(lit("rand"), user_package), func_n2o(rnd, 1)); + reg_fun(intern(lit("random-buf"), user_package), func_n2o(random_buf, 1)); } @@ -35,5 +35,6 @@ val random_state_p(val obj); val random_fixnum(val state); val random(val state, val modulus); val rnd(val modulus, val state); +val random_buf(val size, val state); void rand_compat_fixup(int compat_ver); void rand_init(void); diff --git a/stdlib/doc-syms.tl b/stdlib/doc-syms.tl index 81ec7211..3e2f7cc3 100644 --- a/stdlib/doc-syms.tl +++ b/stdlib/doc-syms.tl @@ -1504,6 +1504,7 @@ ("raise" "N-0108FFCE") ("rand" "N-03A57C86") ("random" "N-03A57C86") + ("random-buf" "N-00161346") ("random-fixnum" "N-03A57C86") ("random-float" "N-01572D27") ("random-state-get-vec" "N-005C0F98") @@ -62307,6 +62307,30 @@ random state object given by the argument to the optional parameter, which defaults to the value of .codn *random-state* . +.coNP Function @ random-buf +.synb +.mets (random-buf << size <> [ random-state ]) +.syne +.desc +The +.code random-buf +function creates a +.code buf +object of the specified +.meta size +fills it with pseudorandom bytes, and returns it. + +The bytes are obtained from the random state object given by the optional +.meta random-state +parameter, which defaults to the value of +.codn *random-state* . + +See the section +.B Buffers +for a description of +.code buf +objects. + .SS* Time .coNP Functions @, time @ time-usec and @ time-nsec .synb |