Skip to content

Commit 3163b09

Browse files
Merge pull request #9 from diffblue/romain/string-of-char-array
Add and use CProverString.ofCharArray
2 parents c9d9226 + b7ca9fd commit 3163b09

File tree

3 files changed

+53
-8
lines changed

3 files changed

+53
-8
lines changed

src/main/java/java/lang/String.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,27 @@ public String(char value[]) {
194194
// this.value = Arrays.copyOf(value, value.length);
195195
}
196196

197+
/**
198+
* Intermediary function for modelling the constructor for
199+
* String(char value[], int offset, int count).
200+
* The code is copied from the original String(char value[], int offset, int count).
201+
*/
202+
private static String CProverStringOfCharArray(char value[], int offset, int count) {
203+
if (offset < 0) {
204+
throw new StringIndexOutOfBoundsException(offset);
205+
}
206+
if (count < 0) {
207+
throw new StringIndexOutOfBoundsException(count);
208+
}
209+
// Note: offset or count might be near -1>>>1.
210+
if (offset > value.length - count) {
211+
throw new StringIndexOutOfBoundsException(offset + count);
212+
}
213+
// DIFFBLUE MODEL LIBRARY Use CProverString function instead of array copy
214+
return CProverString.ofCharArray(value, offset, count);
215+
// this.value = Arrays.copyOfRange(value, offset, offset+count);
216+
}
217+
197218
/**
198219
* Allocates a new {@code String} that contains characters from a subarray
199220
* of the character array argument. The {@code offset} argument is the
@@ -216,11 +237,11 @@ public String(char value[]) {
216237
* characters outside the bounds of the {@code value} array
217238
*
218239
* @diffblue.limitedSupport
219-
* Does not throw exceptions.
220240
* @diffblue.untested
221241
*/
222242
public String(char value[], int offset, int count) {
223-
// DIFFBLUE MODEL LIBRARY This is treated internally in CBMC
243+
// DIFFBLUE MODEL LIBRARY
244+
this(CProverStringOfCharArray(value, offset, count));
224245
// if (offset < 0) {
225246
// throw new StringIndexOutOfBoundsException(offset);
226247
// }

src/main/java/java/lang/StringBuilder.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -241,23 +241,25 @@ public StringBuilder append(CharSequence s, int start, int end) {
241241
*/
242242
@Override
243243
public StringBuilder append(char[] str) {
244-
// DIFFBLUE MODEL LIBRARY: Handled internally by CBMC
244+
// DIFFBLUE MODEL LIBRARY
245+
String string = CProverString.ofCharArray(str, 0, str.length);
246+
return append(string);
245247
// super.append(str);
246248
// return this;
247-
return CProver.nondetWithNullForNotModelled();
248249
}
249250

250251
/**
251252
* @throws IndexOutOfBoundsException {@inheritDoc}
252-
*
253-
* @diffblue.noSupport
253+
* @diffblue.fullSupport
254+
* @diffblue.untested
254255
*/
255256
@Override
256257
public StringBuilder append(char[] str, int offset, int len) {
258+
// DIFFBLUE MODEL LIBRARY
259+
String string = new String(str, offset, len);
260+
return append(string);
257261
// super.append(str, offset, len);
258262
// return this;
259-
CProver.notModelled();
260-
return CProver.nondetWithNullForNotModelled();
261263
}
262264

263265
/**

src/main/java/org/cprover/CProverString.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,4 +388,26 @@ public static StringBuffer insert(
388388
return CProver.nondetWithoutNullForNotModelled();
389389
}
390390

391+
/**
392+
* Converts an array of characters to a string. This uses a loop and
393+
* therefore in test-generation the {@code count} will be limited by the
394+
* unwind parameter.
395+
* This constrains {@code value} to not be null, its length is greater or equal to
396+
* {@code offset + count} and {@code offset} and {@code count} are non-negative.
397+
*
398+
* @param value array of characters which is the source to copy from
399+
* @param offset index in {@code value} of the first character to copy
400+
* @param count number of characters to copy
401+
* @return The created String
402+
*/
403+
public static String ofCharArray(char value[], int offset, int count) {
404+
CProver.assume(value != null);
405+
CProver.assume(value.length - count >= offset
406+
&& offset >= 0 && count >= 0);
407+
StringBuilder builder = new StringBuilder();
408+
for(int i = 0; i < count; i++) {
409+
builder.append(value[offset + i]);
410+
}
411+
return builder.toString();
412+
}
391413
}

0 commit comments

Comments
 (0)