1 /*
   2  * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @summary This exercises String#repeat patterns and limits.
  27  * @run main/othervm -Xmx4G StringRepeat
  28  */
  29 
  30 import java.nio.CharBuffer;
  31 
  32 public class StringRepeat {
  33     public static void main(String... arg) {
  34         test1();
  35         test2();
  36     }
  37 
  38     /*
  39      * Varitions of repeat count.
  40      */
  41     static int[] REPEATS = {
  42         0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
  43         32, 64, 128, 256, 512, 1024, 64 * 1024, 1024 * 1024,
  44         16 * 1024 * 1024
  45     };
  46 
  47     /*
  48      * Varitions of Strings.
  49      */
  50     static String[] STRINGS = new String[] {
  51             "", "\0",  " ", "a", "$", "\u2022",
  52             "ab", "abc", "abcd", "abcde",
  53             "The quick brown fox jumps over the lazy dog."
  54     };
  55 
  56     /*
  57      * Repeat String function tests.
  58      */
  59     static void test1() {
  60         for (int repeat : REPEATS) {
  61             for (String string : STRINGS) {
  62                 long limit = (long)string.length() * (long)repeat;
  63 
  64                 if ((long)(Integer.MAX_VALUE >> 1) <= limit) {
  65                     break;
  66                 }
  67 
  68                 VERIFY(string.repeat(repeat), string, repeat);
  69             }
  70         }
  71     }
  72 
  73     /*
  74      * Repeat String exception tests.
  75      */
  76     static void test2() {
  77         try {
  78             "abc".repeat(-1);
  79             throw new RuntimeException("No exception for negative repeat count");
  80         } catch (IllegalArgumentException ex) {
  81             // Correct
  82         }
  83 
  84         try {
  85             "abc".repeat(Integer.MAX_VALUE - 1);
  86             throw new RuntimeException("No exception for large repeat count");
  87         } catch (OutOfMemoryError ex) {
  88             // Correct
  89         }
  90     }
  91 
  92     static String truncate(String string) {
  93         if (string.length() < 80) {
  94             return string;
  95         }
  96         return string.substring(0, 80) + "...";
  97     }
  98 
  99      /*
 100       * Verify string repeat patterns.
 101       */
 102     static void VERIFY(String result, String string, int repeat) {
 103         if (string.isEmpty() || repeat == 0) {
 104             if (!result.isEmpty()) {
 105                 System.err.format("\"%s\".repeat(%d)%n", truncate(string), repeat);
 106                 System.err.format("Result \"%s\"%n", truncate(result));
 107                 System.err.format("Result expected to be empty, found string of length %d%n", result.length());
 108                 throw new RuntimeException();
 109             }
 110         } else {
 111             int expected = 0;
 112             int count = 0;
 113             for (int offset = result.indexOf(string, expected);
 114                  0 <= offset;
 115                  offset = result.indexOf(string, expected)) {
 116                 count++;
 117                 if (offset != expected) {
 118                     System.err.format("\"%s\".repeat(%d)%n", truncate(string), repeat);
 119                     System.err.format("Result \"%s\"%n", truncate(result));
 120                     System.err.format("Repeat expected at %d, found at = %d%n", expected, offset);
 121                     throw new RuntimeException();
 122                 }
 123                 expected += string.length();
 124             }
 125             if (count != repeat) {
 126                 System.err.format("\"%s\".repeat(%d)%n", truncate(string), repeat);
 127                 System.err.format("Result \"%s\"%n", truncate(result));
 128                 System.err.format("Repeat count expected to be %d, found %d%n", repeat, count);
 129                 throw new RuntimeException();
 130             }
 131         }
 132     }
 133 }