Commit: dccf5afbef67ffd0201da26cc6603c1f42d3668f
Author: Campbell Barton
Date:   Sun Jun 12 00:38:49 2016 +1000
Branches: master
https://developer.blender.org/rBdccf5afbef67ffd0201da26cc6603c1f42d3668f

BLI_rand: add BLI_rng_get_char_n

Use to fill an array of bytes to random values.

===================================================================

M       source/blender/blenlib/BLI_rand.h
M       source/blender/blenlib/intern/rand.c
M       tests/gtests/blenlib/BLI_array_store_test.cc

===================================================================

diff --git a/source/blender/blenlib/BLI_rand.h 
b/source/blender/blenlib/BLI_rand.h
index 7b84ddd..f36d2fa 100644
--- a/source/blender/blenlib/BLI_rand.h
+++ b/source/blender/blenlib/BLI_rand.h
@@ -49,6 +49,7 @@ void        BLI_rng_free(struct RNG *rng) ATTR_NONNULL(1);
 
 void        BLI_rng_seed(struct RNG *rng, unsigned int seed) ATTR_NONNULL(1);
 void        BLI_rng_srandom(struct RNG *rng, unsigned int seed) 
ATTR_NONNULL(1);
+void        BLI_rng_get_char_n(RNG *rng, char *bytes, size_t bytes_len) 
ATTR_NONNULL(1, 2);
 int         BLI_rng_get_int(struct RNG *rng) ATTR_WARN_UNUSED_RESULT 
ATTR_NONNULL(1);
 unsigned int BLI_rng_get_uint(struct RNG *rng) ATTR_WARN_UNUSED_RESULT 
ATTR_NONNULL(1);
 double      BLI_rng_get_double(struct RNG *rng) ATTR_WARN_UNUSED_RESULT 
ATTR_NONNULL(1);
diff --git a/source/blender/blenlib/intern/rand.c 
b/source/blender/blenlib/intern/rand.c
index 66c568a..40d9a3d 100644
--- a/source/blender/blenlib/intern/rand.c
+++ b/source/blender/blenlib/intern/rand.c
@@ -46,6 +46,7 @@
 
 #define MULTIPLIER  0x5DEECE66Dll
 #define MASK        0x0000FFFFFFFFFFFFll
+#define MASK_BYTES   2
 
 #define ADDEND      0xB
 #define LOWSEED     0x330E
@@ -107,6 +108,45 @@ BLI_INLINE void rng_step(RNG *rng)
        rng->X = (MULTIPLIER * rng->X + ADDEND) & MASK;
 }
 
+void BLI_rng_get_char_n(RNG *rng, char *bytes, size_t bytes_len)
+{
+       size_t last_len = 0;
+       size_t trim_len = bytes_len;
+
+#define RAND_STRIDE (sizeof(rng->X) - MASK_BYTES)
+
+       if (trim_len > RAND_STRIDE) {
+               last_len = trim_len % RAND_STRIDE;
+               trim_len = trim_len - last_len;
+       }
+       else {
+               trim_len = 0;
+               last_len = bytes_len;
+       }
+
+       const char *data_src = (void *)&(rng->X);
+       size_t i = 0;
+       while (i != trim_len) {
+               BLI_assert(i < trim_len);
+#ifdef __BIG_ENDIAN__
+               for (size_t j = (RAND_STRIDE + MASK_BYTES) - 1; j != MASK_BYTES 
- 1; j--)
+#else
+               for (size_t j = 0; j != RAND_STRIDE; j++)
+#endif
+               {
+                       bytes[i++] = data_src[j];
+               }
+               rng_step(rng);
+       }
+       if (last_len) {
+               for (size_t j = 0; j != last_len; j++) {
+                       bytes[i++] = data_src[j];
+               }
+       }
+
+#undef RAND_STRIDE
+}
+
 int BLI_rng_get_int(RNG *rng)
 {
        rng_step(rng);
diff --git a/tests/gtests/blenlib/BLI_array_store_test.cc 
b/tests/gtests/blenlib/BLI_array_store_test.cc
index 33fb454..b71dc45 100644
--- a/tests/gtests/blenlib/BLI_array_store_test.cc
+++ b/tests/gtests/blenlib/BLI_array_store_test.cc
@@ -528,15 +528,6 @@ static unsigned int rand_range_i(RNG *rng, unsigned int 
min_i, unsigned int max_
        return min_i + value;
 }
 
-static void rand_bytes(RNG *rng, char *data, int data_len)
-{
-       BLI_assert(data_len != 0);
-       while (data_len--) {
-               *data = BLI_rng_get_uint(rng) % 256;
-               data++;
-       }
-}
-
 static void testbuffer_list_state_random_data(
         ListBase *lb,
         const size_t stride,
@@ -548,7 +539,7 @@ static void testbuffer_list_state_random_data(
        char *data = (char *)MEM_mallocN(data_len, __func__);
 
        if (lb->last == NULL) {
-               rand_bytes(rng, data, data_len);
+               BLI_rng_get_char_n(rng, data, data_len);
        }
        else {
                TestBuffer *tb_last = (TestBuffer *)lb->last;
@@ -557,7 +548,7 @@ static void testbuffer_list_state_random_data(
                }
                else {
                        memcpy(data, tb_last->data, tb_last->data_len);
-                       rand_bytes(rng, &data[tb_last->data_len], data_len - 
tb_last->data_len);
+                       BLI_rng_get_char_n(rng, &data[tb_last->data_len], 
data_len - tb_last->data_len);
                }
 
                /* perform multiple small mutations to the array. */
@@ -583,7 +574,7 @@ static void testbuffer_list_state_random_data(
                                                data_len += stride;
                                                data = (char 
*)MEM_reallocN((void *)data, data_len);
                                                memmove(&data[offset + stride], 
&data[offset], data_len - (offset + stride));
-                                               rand_bytes(rng, &data[offset], 
stride);
+                                               BLI_rng_get_char_n(rng, 
&data[offset], stride);
                                        }
                                        break;
                                }
@@ -608,7 +599,7 @@ static void testbuffer_list_state_random_data(
                                {
                                        if (data_len > 0) {
                                                const unsigned int offset = 
rand_range_i(rng, 0, data_len - stride, stride);
-                                               rand_bytes(rng, &data[offset], 
stride);
+                                               BLI_rng_get_char_n(rng, 
&data[offset], stride);
                                        }
                                        break;
                                }
@@ -667,7 +658,7 @@ static void random_chunk_generate(
        const size_t chunk_size_bytes = stride * chunk_count;
        for (int i = 0; i < chunks_per_buffer; i++) {
                char *data_chunk = (char *)MEM_mallocN(chunk_size_bytes, 
__func__);
-               rand_bytes(rng, data_chunk, chunk_size_bytes);
+               BLI_rng_get_char_n(rng, data_chunk, chunk_size_bytes);
                testchunk_list_add(lb, data_chunk, chunk_size_bytes);
        }
        BLI_rng_free(rng);

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to