Skip to content

Commit

Permalink
Updated readme; deleted stringutils
Browse files Browse the repository at this point in the history
  • Loading branch information
Arachnid committed May 22, 2016
1 parent 183f1f8 commit 3129b17
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 302 deletions.
131 changes: 106 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

# String & slice utility library for Solidity
## Overview
Functionality in this library is largely implemented using an abstraction called a 'slice'. A slice represents a part of a string - anything from the entire string to a single character, or even no characters at all (a 0-length slice). Since a slice only has to specify an offset and a length, copying and manipulating slices is a lot less expensive than copying and manipulating the strings they reference.

To further reduce gas costs, most functions on slice that need to return a slice modify the original one instead of allocating a new one; for instance, `s.split(".")` will return the text up to the first '.', modifying s to only contain the remainder of the string after the '.'. In situations where you do not want to modify the original slice, you can make a copy first with `.copy()`, for example: `s.copy().split(".")`. Try and avoid using this idiom in loops; since Solidity has no memory management, it will result in allocating many short-lived slices that are later discarded.
Expand All @@ -8,7 +9,87 @@ Functions that return two slices come in two versions: a non-allocating version

Functions that have to copy string data will return strings rather than slices; these can be cast back to slices for further processing if required.

## toSlice(string self) internal returns (slice)
## Examples
### Basic usage
import "github.com/Arachnid/solidity-stringutils/strings.sol";

contract Contract {
using strings for *;

// ...
}

### Getting the character length of a string
var len = "Unicode snowman ☃".toSlice().len(); // 17

### Splitting a string around a delimiter
var s = "foo bar baz".toSlice();
var foo = s.split(" ".toSlice());

After the above code executes, `s` is now "bar baz", and `foo` is now "foo".

### Splitting a string into an array
var s = "www.google.com".toSlice();
var delim = ".".toSlice();
var parts = new strings.slice[](s.count(delim));
for(uint i = 0; i < parts.length; i++) {
parts[i] = s.split(delim).toString();
}

### Extracting the middle part of a string
var s = "www.google.com".toSlice();
strings.slice memory part;
s.split(".".toSlice(), part); // part and return value is "www"
s.split(".".toSlice(), part); // part and return value is "google"

This approach uses less memory than the above, by reusing the slice `part` for each section of string extracted.

### Converting a slice back to a string
var myString = mySlice.toString();

### Finding and returning the first occurrence of a substring
var s = "A B C B D".toSlice();
s.find("B".toSlice()); // "B C B D"

`find` modifies `s` to contain the part of the string from the first match onwards.

### Finding and returning the last occurrence of a substring
var s = "A B C B D".toSlice();
s.rfind("B".toSlice()); // "A B C B"

`rfind` modifies `s` to contain the part of the string from the last match back to the start.

### Finding without modifying the original slice.
var s = "A B C B D".toSlice();
var substring = s.copy().rfind("B".toSlice()); // "A B C B"

`copy` lets you cheaply duplicate a slice so you don't modify the original.

### Prefix and suffix matching
var s = "A B C B D".toSlice();
s.startsWith("A".toSlice()); // True
s.endsWith("D".toSlice()); // True
s.startsWith("B".toSlice()); // False

### Removing a prefix or suffix
var s = "A B C B D".toSlice();
s.beyond("A ".toSlice()).until(" D".toSlice()); // "B C B"

`beyond` modifies `s` to contain the text after its argument; `until` modifies `s` to contain the text up to its argument. If the argument isn't found, `s` is unmodified.

### Finding and returning the string up to the first match
var s = "A B C B D".toSlice();
var needle = "B".toSlice();
var substring = s.until(s.copy().find(needle).beyond(needle));

Calling `find` on a copy of `s` returns the part of the string from `needle` onwards; calling `.beyond(needle)` removes `needle` as a prefix, and finally calling `s.until()` removes the entire end of the string, leaving everything up to and including the first match.

### Concatenating strings
var s = "abc".toSlice().concat("def".toSlice()); // "abcdef"

## Reference

### toSlice(string self) internal returns (slice)
Returns a slice containing the entire string.

Arguments:
Expand All @@ -17,7 +98,7 @@ Arguments:

Returns A newly allocated slice containing the entire string.

## copy(slice self) internal returns (slice)
### copy(slice self) internal returns (slice)
Returns a new slice containing the same data as the current slice.

Arguments:
Expand All @@ -26,7 +107,7 @@ Arguments:

Returns A new slice containing the same data as `self`.

## toString(slice self) internal returns (string)
### toString(slice self) internal returns (string)

Copies a slice to a new string.

Expand All @@ -36,7 +117,7 @@ Arguments:

Returns A newly allocated string containing the slice's text.

## len(slice self) internal returns (uint)
### len(slice self) internal returns (uint)

Returns the length in runes of the slice. Note that this operation takes time proportional to the length of the slice; avoid using it in loops, and call `slice.empty()` if you only need to know whether the slice is empty or not.

Expand All @@ -46,7 +127,7 @@ Arguments:

Returns The length of the slice in runes.

## empty(slice self) internal returns (bool)
### empty(slice self) internal returns (bool)

Returns true if the slice is empty (has a length of 0).

Expand All @@ -56,7 +137,7 @@ Arguments:

Returns True if the slice is empty, False otherwise.

## compare(slice self, slice other) internal returns (int)
### compare(slice self, slice other) internal returns (int)

Returns a positive number if `other` comes lexicographically after `self`, a negative number if it comes before, or zero if the contents of the two slices are equal. Comparison is done per-rune, on unicode codepoints.

Expand All @@ -67,7 +148,7 @@ Arguments:

Returns The result of the comparison.

## equals(slice self, slice other) internal returns (bool)
### equals(slice self, slice other) internal returns (bool)

Returns true if the two slices contain the same text.

Expand All @@ -78,7 +159,7 @@ Arguments:

Returns True if the slices are equal, false otherwise.

## nextRune(slice self, slice rune) internal returns (slice)
### nextRune(slice self, slice rune) internal returns (slice)

Extracts the first rune in the slice into `rune`, advancing the slice to point to the next rune and returning `self`.

Expand All @@ -89,7 +170,7 @@ Arguments:

Returns `rune`.

## nextRune(slice self) internal returns (slice ret)
### nextRune(slice self) internal returns (slice ret)

Returns the first rune in the slice, advancing the slice to point to the next rune.

Expand All @@ -99,7 +180,7 @@ Arguments:

Returns A slice containing only the first rune from `self`.

## ord(slice self) internal returns (uint ret)
### ord(slice self) internal returns (uint ret)

Returns the number of the first codepoint in the slice.

Expand All @@ -109,7 +190,7 @@ Arguments:

Returns The number of the first codepoint in the slice.

## keccak(slice self) internal returns (bytes32 ret)
### keccak(slice self) internal returns (bytes32 ret)

Returns the keccak-256 hash of the slice.

Expand All @@ -119,7 +200,7 @@ Arguments:

Returns The hash of the slice.

## startsWith(slice self, slice needle) internal returns (bool)
### startsWith(slice self, slice needle) internal returns (bool)

Returns true if `self` starts with `needle`.

Expand All @@ -130,7 +211,7 @@ Arguments:

Returns True if the slice starts with the provided text, false otherwise.

## beyond(slice self, slice needle) internal returns (slice)
### beyond(slice self, slice needle) internal returns (slice)

If `self` starts with `needle`, `needle` is removed from the beginning of `self`. Otherwise, `self` is unmodified.

Expand All @@ -141,7 +222,7 @@ Arguments:

Returns `self`

## endsWith(slice self, slice needle) internal returns (bool)
### endsWith(slice self, slice needle) internal returns (bool)

Returns true if the slice ends with `needle`.

Expand All @@ -152,7 +233,7 @@ Arguments:

Returns True if the slice starts with the provided text, false otherwise.

## until(slice self, slice needle) internal returns (slice)
### until(slice self, slice needle) internal returns (slice)

If `self` ends with `needle`, `needle` is removed from the end of `self`. Otherwise, `self` is unmodified.

Expand All @@ -163,7 +244,7 @@ Arguments:

Returns `self`

## find(slice self, slice needle) internal returns (slice)
### find(slice self, slice needle) internal returns (slice)

Modifies `self` to contain everything from the first occurrence of `needle` to the end of the slice. `self` is set to the empty slice if `needle` is not found.

Expand All @@ -174,7 +255,7 @@ Arguments:

Returns `self`.

## rfind(slice self, slice needle) internal returns (slice)
### rfind(slice self, slice needle) internal returns (slice)

Modifies `self` to contain the part of the string from the start of `self` to the end of the first occurrence of `needle`. If `needle` is not found, `self` is set to the empty slice.

Expand All @@ -185,7 +266,7 @@ Arguments:

Returns `self`.

## split(slice self, slice needle, slice token) internal returns (slice)
### split(slice self, slice needle, slice token) internal returns (slice)

Splits the slice, setting `self` to everything after the first occurrence of `needle`, and `token` to everything before it. If `needle` does not occur in `self`, `self` is set to the empty slice, and `token` is set to the entirety of `self`.

Expand All @@ -197,7 +278,7 @@ Arguments:

Returns `token`.

## split(slice self, slice needle) internal returns (slice token)
### split(slice self, slice needle) internal returns (slice token)

Splits the slice, setting `self` to everything after the first occurrence of `needle`, and returning everything before it. If `needle` does not occur in `self`, `self` is set to the empty slice, and the entirety of `self` is returned.

Expand All @@ -208,7 +289,7 @@ Arguments:

Returns The part of `self` up to the first occurrence of `delim`.

## rsplit(slice self, slice needle, slice token) internal returns (slice)
### rsplit(slice self, slice needle, slice token) internal returns (slice)

Splits the slice, setting `self` to everything before the last occurrence of `needle`, and `token` to everything after it. If `needle` does not occur in `self`, `self` is set to the empty slice, and `token` is set to the entirety of `self`.

Expand All @@ -220,7 +301,7 @@ Arguments:

Returns `token`.

## rsplit(slice self, slice needle) internal returns (slice token)
### rsplit(slice self, slice needle) internal returns (slice token)

Splits the slice, setting `self` to everything before the last occurrence of `needle`, and returning everything after it. If `needle` does not occur in `self`, `self` is set to the empty slice, and the entirety of `self` is returned.

Expand All @@ -231,7 +312,7 @@ Arguments:

Returns The part of `self` after the last occurrence of `delim`.

## count(slice self, slice needle) internal returns (uint count)
### count(slice self, slice needle) internal returns (uint count)

Counts the number of nonoverlapping occurrences of `needle` in `self`.

Expand All @@ -242,7 +323,7 @@ Arguments:

Returns The number of occurrences of `needle` found in `self`.

## contains(slice self, slice needle) internal returns (bool)
### contains(slice self, slice needle) internal returns (bool)

Returns True if `self` contains `needle`.

Expand All @@ -253,7 +334,7 @@ Arguments:

Returns True if `needle` is found in `self`, false otherwise.

## concat(slice self, slice other) internal returns (string)
### concat(slice self, slice other) internal returns (string)

Returns a newly allocated string containing the concatenation of `self` and `other`.

Expand All @@ -264,7 +345,7 @@ Arguments:

Returns The concatenation of the two strings.

## join(slice self, slice[] parts) internal returns (string)
### join(slice self, slice[] parts) internal returns (string)

Joins an array of slices, using `self` as a delimiter, returning a newly allocated string.

Expand Down
Loading

0 comments on commit 3129b17

Please sign in to comment.