1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // https://developers.google.com/protocol-buffers/ 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions are 7 // met: 8 // 9 // * Redistributions of source code must retain the above copyright 10 // notice, this list of conditions and the following disclaimer. 11 // * Redistributions in binary form must reproduce the above 12 // copyright notice, this list of conditions and the following disclaimer 13 // in the documentation and/or other materials provided with the 14 // distribution. 15 // * Neither the name of Google Inc. nor the names of its 16 // contributors may be used to endorse or promote products derived from 17 // this software without specific prior written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31 package com.google.protobuf; 32 33 import java.util.Random; 34 35 /** Utility class that provides data primitives for filling out protobuf messages. */ 36 public final class ExperimentalTestDataProvider { 37 private static final Random RANDOM = new Random(100); 38 39 private final Varint32Provider varint32s = new Varint32Provider(); 40 private final Varint64Provider varint64s = new Varint64Provider(); 41 private final int stringLength; 42 ExperimentalTestDataProvider(int stringLength)43 public ExperimentalTestDataProvider(int stringLength) { 44 this.stringLength = stringLength; 45 } 46 getDouble()47 public double getDouble() { 48 double value = 0.0; 49 while (Double.compare(0.0, value) == 0) { 50 value = RANDOM.nextDouble(); 51 } 52 return value; 53 } 54 getFloat()55 public float getFloat() { 56 float value = 0.0f; 57 while (Float.compare(0.0f, value) == 0) { 58 value = RANDOM.nextFloat(); 59 } 60 return value; 61 } 62 getLong()63 public long getLong() { 64 return varint64s.getLong(); 65 } 66 getInt()67 public int getInt() { 68 return varint32s.getInt(); 69 } 70 getBool()71 public boolean getBool() { 72 return true; 73 } 74 getEnum()75 public int getEnum() { 76 return Math.abs(getInt()) % 3; 77 } 78 getString()79 public String getString() { 80 StringBuilder builder = new StringBuilder(stringLength); 81 for (int i = 0; i < stringLength; ++i) { 82 builder.append((char) (RANDOM.nextInt('z' - 'a') + 'a')); 83 } 84 return builder.toString(); 85 } 86 getBytes()87 public ByteString getBytes() { 88 return ByteString.copyFromUtf8(getString()); 89 } 90 91 /** 92 * Iterator over integer values. Uses a simple distribution over 32-bit varints (generally 93 * favoring smaller values). 94 */ 95 private static final class Varint32Provider { 96 private static final int[][] VALUES = { 97 new int[] {1, 50, 100, 127}, // 1 byte values 98 new int[] {128, 500, 10000, 16383}, // 2 bytes values 99 new int[] {16384, 50000, 1000000, 2097151}, // 3 bytes values 100 new int[] {2097152, 10000000, 200000000, 268435455}, // 4 bytes values 101 new int[] {268435456, 0x30000000, 0x7FFFFFFF, 0xFFFFFFFF} // 5 bytes values 102 }; 103 104 /** Number of samples that should be taken from each value array. */ 105 private static final int[] NUM_SAMPLES = {3, 2, 1, 1, 2}; 106 107 /** 108 * The index into the {@link #VALUES} array that identifies the list of samples currently being 109 * iterated over. 110 */ 111 private int listIndex; 112 113 /** The index of the next sample within a list. */ 114 private int sampleIndex; 115 116 /** The number of successive samples that have been taken from the current list. */ 117 private int samplesTaken; 118 getInt()119 public int getInt() { 120 if (samplesTaken++ > NUM_SAMPLES[listIndex]) { 121 // Done taking samples from this list. Go to the next one. 122 listIndex = (listIndex + 1) % VALUES.length; 123 sampleIndex = 0; 124 samplesTaken = 0; 125 } 126 127 int value = VALUES[listIndex][sampleIndex]; 128 129 // All lists are exactly 4 long (i.e. power of 2), so we can optimize the mod operation 130 // with masking. 131 sampleIndex = (sampleIndex + 1) & 3; 132 133 return value; 134 } 135 } 136 137 /** 138 * Iterator over integer values. Uses a simple distribution over 64-bit varints (generally 139 * favoring smaller values). 140 */ 141 private static final class Varint64Provider { 142 private static final long[][] VALUES = { 143 new long[] {1, 50, 100, 127}, 144 new long[] {128, 500, 10000, 16383}, 145 new long[] {16384, 50000, 1000000, 2097151}, 146 new long[] {2097152, 10000000, 200000000, 268435455}, 147 new long[] {268435456, 0x30000000, 0x7FFFFFFF, 34359738367L}, 148 new long[] {34359738368L, 2000000000000L, 4000000000000L, 4398046511103L}, 149 new long[] {4398046511104L, 200000000000000L, 500000000000000L, 562949953421311L}, 150 new long[] {0x4000000000000L, 0x5000000000000L, 0x6000000000000L, 0x0FFFFFFFFFFFFFFL}, 151 new long[] {0x100000000000000L, 0x3FFFFFFFFFFFFFFFL, 0x5FFFFFFFFFFFFFFL, 0x7FFFFFFFFFFFFFFFL}, 152 new long[] { 153 0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL 154 } 155 }; 156 157 /** Number of samples that should be taken from each value array. */ 158 private static final int[] NUM_SAMPLES = {4, 2, 2, 1, 1, 1, 1, 2, 2, 4}; 159 160 /** 161 * The index into the {@link #VALUES} array that identifies the list of samples currently being 162 * iterated over. 163 */ 164 private int listIndex; 165 166 /** The index of the next sample within a list. */ 167 private int sampleIndex; 168 169 /** The number of successive samples that have been taken from the current list. */ 170 private int samplesTaken; 171 getLong()172 public long getLong() { 173 if (samplesTaken++ > NUM_SAMPLES[listIndex]) { 174 // Done taking samples from this list. Go to the next one. 175 listIndex = (listIndex + 1) % VALUES.length; 176 sampleIndex = 0; 177 samplesTaken = 0; 178 } 179 180 long value = VALUES[listIndex][sampleIndex]; 181 182 // All lists are exactly 4 long (i.e. power of 2), so we can optimize the mod operation 183 // with masking. 184 sampleIndex = (sampleIndex + 1) & 3; 185 186 return value; 187 } 188 } 189 } 190