summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--rand.c41
-rw-r--r--rand.h1
-rw-r--r--stdlib/doc-syms.tl1
-rw-r--r--txr.124
4 files changed, 67 insertions, 0 deletions
diff --git a/rand.c b/rand.c
index d30838ce..3ee6646c 100644
--- a/rand.c
+++ b/rand.c
@@ -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));
}
diff --git a/rand.h b/rand.h
index a739554d..e04069f7 100644
--- a/rand.h
+++ b/rand.h
@@ -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")
diff --git a/txr.1 b/txr.1
index 2a8afc1d..6d7138a8 100644
--- a/txr.1
+++ b/txr.1
@@ -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