com.azure.core.util.UrlTokenizer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of azure-core Show documentation
Show all versions of azure-core Show documentation
This package contains core types for Azure Java clients.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package com.azure.core.util;
class UrlTokenizer {
private final String text;
private final int textLength;
private UrlTokenizerState state;
private int currentIndex;
private UrlToken currentToken;
UrlTokenizer(String text) {
this(text, UrlTokenizerState.SCHEME_OR_HOST);
}
UrlTokenizer(String text, UrlTokenizerState state) {
this.text = text;
this.textLength = (text == null ? 0 : text.length());
this.state = state;
this.currentIndex = 0;
this.currentToken = null;
}
private boolean hasCurrentCharacter() {
return currentIndex < textLength;
}
private char currentCharacter() {
return text.charAt(currentIndex);
}
private void nextCharacter() {
if (hasCurrentCharacter()) {
currentIndex += 1;
}
}
/*
* Checks if the next range of characters matches the scheme-host separator (://)
*/
private boolean peekMatchesSchemeSeparator(boolean step) {
if ("://".regionMatches(0, text, currentIndex, 3)) {
if (step) {
currentIndex += 3;
}
return true;
}
return false;
}
UrlToken current() {
return currentToken;
}
boolean next() {
if (!hasCurrentCharacter()) {
currentToken = null;
} else {
char c;
switch (state) {
case SCHEME:
final String scheme = readUntilNotLetterOrDigit();
currentToken = UrlToken.scheme(scheme);
if (!hasCurrentCharacter()) {
state = UrlTokenizerState.DONE;
} else {
state = UrlTokenizerState.HOST;
}
break;
case SCHEME_OR_HOST:
final String schemeOrHost = readUntil(true);
if (!hasCurrentCharacter()) {
currentToken = UrlToken.host(schemeOrHost);
state = UrlTokenizerState.DONE;
break;
}
c = currentCharacter();
if (c == ':') {
if (peekMatchesSchemeSeparator(false)) {
currentToken = UrlToken.scheme(schemeOrHost);
state = UrlTokenizerState.HOST;
} else {
currentToken = UrlToken.host(schemeOrHost);
state = UrlTokenizerState.PORT;
}
} else if (c == '/') {
currentToken = UrlToken.host(schemeOrHost);
state = UrlTokenizerState.PATH;
} else if (c == '?') {
currentToken = UrlToken.host(schemeOrHost);
state = UrlTokenizerState.QUERY;
}
break;
case HOST:
peekMatchesSchemeSeparator(true);
final String host = readUntil(true);
currentToken = UrlToken.host(host);
if (!hasCurrentCharacter()) {
state = UrlTokenizerState.DONE;
break;
}
c = currentCharacter();
if (c == ':') {
state = UrlTokenizerState.PORT;
} else if (c == '/') {
state = UrlTokenizerState.PATH;
} else {
state = UrlTokenizerState.QUERY;
}
break;
case PORT:
c = currentCharacter();
if (c == ':') {
nextCharacter();
}
final String port = readUntil(false);
currentToken = UrlToken.port(port);
if (!hasCurrentCharacter()) {
state = UrlTokenizerState.DONE;
break;
}
if (currentCharacter() == '/') {
state = UrlTokenizerState.PATH;
} else {
state = UrlTokenizerState.QUERY;
}
break;
case PATH:
int index = text.indexOf('?', currentIndex);
String path;
if (index == -1) {
path = text.substring(currentIndex);
currentIndex = textLength;
} else {
path = text.substring(currentIndex, index);
currentIndex = index;
}
currentToken = UrlToken.path(path);
if (!hasCurrentCharacter()) {
state = UrlTokenizerState.DONE;
} else {
state = UrlTokenizerState.QUERY;
}
break;
case QUERY:
if (currentCharacter() == '?') {
nextCharacter();
}
final String query = readRemaining();
currentToken = UrlToken.query(query);
state = UrlTokenizerState.DONE;
break;
default:
break;
}
}
return currentToken != null;
}
private String readUntilNotLetterOrDigit() {
if (!hasCurrentCharacter()) {
return "";
}
int start = currentIndex;
while (hasCurrentCharacter()) {
final char currentCharacter = currentCharacter();
if (!Character.isLetterOrDigit(currentCharacter)) {
return text.substring(start, currentIndex);
}
nextCharacter();
}
return text.substring(start);
}
private String readUntil(boolean checkForColon) {
if (!hasCurrentCharacter()) {
return "";
}
int start = currentIndex;
while (hasCurrentCharacter()) {
char c = currentCharacter();
if ((checkForColon && c == ':') || c == '/' || c == '?') {
return text.substring(start, currentIndex);
}
nextCharacter();
}
return text.substring(start);
}
private String readRemaining() {
String result = "";
if (currentIndex < textLength) {
result = text.substring(currentIndex, textLength);
currentIndex = textLength;
}
return result;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy