mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-23 00:24:11 -08:00
Merge branch 'date' into date2
Conflicts: teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRHelper.java
This commit is contained in:
commit
2cab17dee4
|
@ -39,4 +39,20 @@ public class CLDRHelper {
|
||||||
@GeneratedBy(CLDRHelperNativeGenerator.class)
|
@GeneratedBy(CLDRHelperNativeGenerator.class)
|
||||||
@PluggableDependency(CLDRHelperNativeGenerator.class)
|
@PluggableDependency(CLDRHelperNativeGenerator.class)
|
||||||
private static native String getLikelySubtagsImpl(String localeCode);
|
private static native String getLikelySubtagsImpl(String localeCode);
|
||||||
|
|
||||||
|
public static String[] resolveEras(String localeCode) {
|
||||||
|
readErasFromCLDR();
|
||||||
|
String[] eras = getEras(localeCode);
|
||||||
|
if (eras == null) {
|
||||||
|
eras = getEras("root");
|
||||||
|
}
|
||||||
|
return eras;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Defined by JCLPlugin
|
||||||
|
private static native void readErasFromCLDR();
|
||||||
|
|
||||||
|
@GeneratedBy(CLDRHelperNativeGenerator.class)
|
||||||
|
@PluggableDependency(CLDRHelperNativeGenerator.class)
|
||||||
|
private static native String[] getEras(String localeCode);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,10 @@ public class CLDRHelperNativeGenerator implements Generator, DependencyPlugin {
|
||||||
case "getLikelySubtagsImpl":
|
case "getLikelySubtagsImpl":
|
||||||
method.getResult().propagate("java.lang.String");
|
method.getResult().propagate("java.lang.String");
|
||||||
break;
|
break;
|
||||||
|
case "getEras":
|
||||||
|
method.getResult().propagate("[java.lang.String;");
|
||||||
|
method.getResult().getArrayItem().propagate("java.lang.String");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,6 +50,23 @@ public class CLDRHelperNativeGenerator implements Generator, DependencyPlugin {
|
||||||
.append(context.getParameterName(1)).append(")];").softNewLine();
|
.append(context.getParameterName(1)).append(")];").softNewLine();
|
||||||
writer.append("return data ? $rt_str(data) : null;").softNewLine();
|
writer.append("return data ? $rt_str(data) : null;").softNewLine();
|
||||||
break;
|
break;
|
||||||
|
case "getEras":
|
||||||
|
generateGetArray(context, writer, "eras");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void generateGetArray(GeneratorContext context, SourceWriter writer, String name) throws IOException {
|
||||||
|
writer.append("var data = ").appendClass("java.util.Locale").append(".$CLDR.").append(name)
|
||||||
|
.append("[$rt_ustr(").append(context.getParameterName(1)).append(")];").softNewLine();
|
||||||
|
writer.append("if (!data) {").indent().softNewLine();
|
||||||
|
writer.append("return null;");
|
||||||
|
writer.outdent().append("}").softNewLine();
|
||||||
|
writer.append("var result = $rt_createArray(").appendClass("java.lang.String)")
|
||||||
|
.append(", data.length);").softNewLine();
|
||||||
|
writer.append("for (var i = 0; i < data.length; ++i) {").indent().softNewLine();
|
||||||
|
writer.append("result.data[i] = $rt_str(data[i])").softNewLine();
|
||||||
|
writer.outdent().append("}").softNewLine();
|
||||||
|
writer.append("return result;").softNewLine();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.teavm.classlib.java.text;
|
||||||
|
|
||||||
|
public class Annotation {
|
||||||
|
private Object value;
|
||||||
|
|
||||||
|
public Annotation(Object attribute) {
|
||||||
|
value = attribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return getClass().getName() + "[value=" + value + ']';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,144 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.teavm.classlib.java.text;
|
||||||
|
|
||||||
|
import org.teavm.classlib.java.io.TSerializable;
|
||||||
|
import org.teavm.classlib.java.util.TMap;
|
||||||
|
import org.teavm.classlib.java.util.TSet;
|
||||||
|
|
||||||
|
public interface AttributedCharacterIterator extends CharacterIterator {
|
||||||
|
|
||||||
|
public static class Attribute implements TSerializable {
|
||||||
|
public static final Attribute INPUT_METHOD_SEGMENT = new Attribute(
|
||||||
|
"input_method_segment");
|
||||||
|
|
||||||
|
public static final Attribute LANGUAGE = new Attribute("language");
|
||||||
|
|
||||||
|
public static final Attribute READING = new Attribute("reading");
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
protected Attribute(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean equals(Object object) {
|
||||||
|
return this == object;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final int hashCode() {
|
||||||
|
return super.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return getClass().getName() + '(' + getName() + ')';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a set of attributes present in the {@code
|
||||||
|
* AttributedCharacterIterator}. An empty set is returned if no attributes
|
||||||
|
* were defined.
|
||||||
|
*
|
||||||
|
* @return a set of attribute keys; may be empty.
|
||||||
|
*/
|
||||||
|
public TSet<Attribute> getAllAttributeKeys();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value stored in the attribute for the current character. If
|
||||||
|
* the attribute was not defined then {@code null} is returned.
|
||||||
|
*
|
||||||
|
* @param attribute the attribute for which the value should be returned.
|
||||||
|
* @return the value of the requested attribute for the current character or
|
||||||
|
* {@code null} if it was not defined.
|
||||||
|
*/
|
||||||
|
public Object getAttribute(Attribute attribute);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a map of all attributes of the current character. If no
|
||||||
|
* attributes were defined for the current character then an empty map is
|
||||||
|
* returned.
|
||||||
|
*
|
||||||
|
* @return a map of all attributes for the current character or an empty
|
||||||
|
* map.
|
||||||
|
*/
|
||||||
|
public TMap<Attribute, Object> getAttributes();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the index of the last character in the run having the same
|
||||||
|
* attributes as the current character.
|
||||||
|
*
|
||||||
|
* @return the index of the last character of the current run.
|
||||||
|
*/
|
||||||
|
public int getRunLimit();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the index of the last character in the run that has the same
|
||||||
|
* attribute value for the given attribute as the current character.
|
||||||
|
*
|
||||||
|
* @param attribute
|
||||||
|
* the attribute which the run is based on.
|
||||||
|
* @return the index of the last character of the current run.
|
||||||
|
*/
|
||||||
|
public int getRunLimit(Attribute attribute);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the index of the last character in the run that has the same
|
||||||
|
* attribute values for the attributes in the set as the current character.
|
||||||
|
*
|
||||||
|
* @param attributes
|
||||||
|
* the set of attributes which the run is based on.
|
||||||
|
* @return the index of the last character of the current run.
|
||||||
|
*/
|
||||||
|
public int getRunLimit(TSet<? extends Attribute> attributes);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the index of the first character in the run that has the same
|
||||||
|
* attributes as the current character.
|
||||||
|
*
|
||||||
|
* @return the index of the last character of the current run.
|
||||||
|
*/
|
||||||
|
public int getRunStart();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the index of the first character in the run that has the same
|
||||||
|
* attribute value for the given attribute as the current character.
|
||||||
|
*
|
||||||
|
* @param attribute
|
||||||
|
* the attribute which the run is based on.
|
||||||
|
* @return the index of the last character of the current run.
|
||||||
|
*/
|
||||||
|
public int getRunStart(Attribute attribute);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the index of the first character in the run that has the same
|
||||||
|
* attribute values for the attributes in the set as the current character.
|
||||||
|
*
|
||||||
|
* @param attributes
|
||||||
|
* the set of attributes which the run is based on.
|
||||||
|
* @return the index of the last character of the current run.
|
||||||
|
*/
|
||||||
|
public int getRunStart(TSet<? extends Attribute> attributes);
|
||||||
|
}
|
|
@ -0,0 +1,630 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.teavm.classlib.java.text;
|
||||||
|
|
||||||
|
import org.teavm.classlib.java.text.AttributedCharacterIterator.Attribute;
|
||||||
|
import org.teavm.classlib.java.util.*;
|
||||||
|
|
||||||
|
public class AttributedString {
|
||||||
|
|
||||||
|
String text;
|
||||||
|
|
||||||
|
TMap<AttributedCharacterIterator.Attribute, TList<Range>> attributeMap;
|
||||||
|
|
||||||
|
static class Range {
|
||||||
|
int start;
|
||||||
|
|
||||||
|
int end;
|
||||||
|
|
||||||
|
Object value;
|
||||||
|
|
||||||
|
Range(int s, int e, Object v) {
|
||||||
|
start = s;
|
||||||
|
end = e;
|
||||||
|
value = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class AttributedIterator implements AttributedCharacterIterator {
|
||||||
|
|
||||||
|
private int begin, end, offset;
|
||||||
|
|
||||||
|
private AttributedString attrString;
|
||||||
|
|
||||||
|
private THashSet<Attribute> attributesAllowed;
|
||||||
|
|
||||||
|
AttributedIterator(AttributedString attrString) {
|
||||||
|
this.attrString = attrString;
|
||||||
|
begin = 0;
|
||||||
|
end = attrString.text.length();
|
||||||
|
offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
AttributedIterator(AttributedString attrString, AttributedCharacterIterator.Attribute[] attributes, int begin,
|
||||||
|
int end) {
|
||||||
|
if (begin < 0 || end > attrString.text.length() || begin > end) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
this.begin = begin;
|
||||||
|
this.end = end;
|
||||||
|
offset = begin;
|
||||||
|
this.attrString = attrString;
|
||||||
|
if (attributes != null) {
|
||||||
|
THashSet<Attribute> set = new THashSet<>((attributes.length * 4 / 3) + 1);
|
||||||
|
for (int i = attributes.length; --i >= 0;) {
|
||||||
|
set.add(attributes[i]);
|
||||||
|
}
|
||||||
|
attributesAllowed = set;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public Object clone() {
|
||||||
|
try {
|
||||||
|
AttributedIterator clone = (AttributedIterator) super.clone();
|
||||||
|
if (attributesAllowed != null) {
|
||||||
|
clone.attributesAllowed = (THashSet<Attribute>) attributesAllowed.clone();
|
||||||
|
}
|
||||||
|
return clone;
|
||||||
|
} catch (CloneNotSupportedException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char current() {
|
||||||
|
if (offset == end) {
|
||||||
|
return DONE;
|
||||||
|
}
|
||||||
|
return attrString.text.charAt(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char first() {
|
||||||
|
if (begin == end) {
|
||||||
|
return DONE;
|
||||||
|
}
|
||||||
|
offset = begin;
|
||||||
|
return attrString.text.charAt(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBeginIndex() {
|
||||||
|
return begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getEndIndex() {
|
||||||
|
return end;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIndex() {
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean inRange(Range range) {
|
||||||
|
if (!(range.value instanceof Annotation)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return range.start >= begin && range.start < end && range.end > begin && range.end <= end;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean inRange(TList<Range> ranges) {
|
||||||
|
TIterator<Range> it = ranges.iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
Range range = it.next();
|
||||||
|
if (range.start >= begin && range.start < end) {
|
||||||
|
return !(range.value instanceof Annotation) || (range.end > begin && range.end <= end);
|
||||||
|
} else if (range.end > begin && range.end <= end) {
|
||||||
|
return !(range.value instanceof Annotation) || (range.start >= begin && range.start < end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TSet<AttributedIterator.Attribute> getAllAttributeKeys() {
|
||||||
|
if (begin == 0 && end == attrString.text.length() && attributesAllowed == null) {
|
||||||
|
return attrString.attributeMap.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
TSet<AttributedIterator.Attribute> result = new THashSet<>((attrString.attributeMap.size() * 4 / 3) + 1);
|
||||||
|
TIterator<TMap.Entry<Attribute, TList<Range>>> it = attrString.attributeMap.entrySet().iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
TMap.Entry<Attribute, TList<Range>> entry = it.next();
|
||||||
|
if (attributesAllowed == null || attributesAllowed.contains(entry.getKey())) {
|
||||||
|
TList<Range> ranges = entry.getValue();
|
||||||
|
if (inRange(ranges)) {
|
||||||
|
result.add(entry.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object currentValue(TList<Range> ranges) {
|
||||||
|
TIterator<Range> it = ranges.iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
Range range = it.next();
|
||||||
|
if (offset >= range.start && offset < range.end) {
|
||||||
|
return inRange(range) ? range.value : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getAttribute(AttributedCharacterIterator.Attribute attribute) {
|
||||||
|
if (attributesAllowed != null && !attributesAllowed.contains(attribute)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
TArrayList<Range> ranges = (TArrayList<Range>) attrString.attributeMap.get(attribute);
|
||||||
|
if (ranges == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return currentValue(ranges);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TMap<Attribute, Object> getAttributes() {
|
||||||
|
TMap<Attribute, Object> result = new THashMap<>((attrString.attributeMap.size() * 4 / 3) + 1);
|
||||||
|
TIterator<TMap.Entry<Attribute, TList<Range>>> it = attrString.attributeMap.entrySet().iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
TMap.Entry<Attribute, TList<Range>> entry = it.next();
|
||||||
|
if (attributesAllowed == null || attributesAllowed.contains(entry.getKey())) {
|
||||||
|
Object value = currentValue(entry.getValue());
|
||||||
|
if (value != null) {
|
||||||
|
result.put(entry.getKey(), value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRunLimit() {
|
||||||
|
return getRunLimit(getAllAttributeKeys());
|
||||||
|
}
|
||||||
|
|
||||||
|
private int runLimit(TList<Range> ranges) {
|
||||||
|
int result = end;
|
||||||
|
TListIterator<Range> it = ranges.listIterator(ranges.size());
|
||||||
|
while (it.hasPrevious()) {
|
||||||
|
Range range = it.previous();
|
||||||
|
if (range.end <= begin) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (offset >= range.start && offset < range.end) {
|
||||||
|
return inRange(range) ? range.end : result;
|
||||||
|
} else if (offset >= range.end) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result = range.start;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRunLimit(AttributedCharacterIterator.Attribute attribute) {
|
||||||
|
if (attributesAllowed != null && !attributesAllowed.contains(attribute)) {
|
||||||
|
return end;
|
||||||
|
}
|
||||||
|
TArrayList<Range> ranges = (TArrayList<Range>) attrString.attributeMap.get(attribute);
|
||||||
|
if (ranges == null) {
|
||||||
|
return end;
|
||||||
|
}
|
||||||
|
return runLimit(ranges);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRunLimit(TSet<? extends Attribute> attributes) {
|
||||||
|
int limit = end;
|
||||||
|
TIterator<? extends Attribute> it = attributes.iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
AttributedCharacterIterator.Attribute attribute = it.next();
|
||||||
|
int newLimit = getRunLimit(attribute);
|
||||||
|
if (newLimit < limit) {
|
||||||
|
limit = newLimit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRunStart() {
|
||||||
|
return getRunStart(getAllAttributeKeys());
|
||||||
|
}
|
||||||
|
|
||||||
|
private int runStart(TList<Range> ranges) {
|
||||||
|
int result = begin;
|
||||||
|
TIterator<Range> it = ranges.iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
Range range = it.next();
|
||||||
|
if (range.start >= end) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (offset >= range.start && offset < range.end) {
|
||||||
|
return inRange(range) ? range.start : result;
|
||||||
|
} else if (offset < range.start) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result = range.end;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRunStart(AttributedCharacterIterator.Attribute attribute) {
|
||||||
|
if (attributesAllowed != null && !attributesAllowed.contains(attribute)) {
|
||||||
|
return begin;
|
||||||
|
}
|
||||||
|
TArrayList<Range> ranges = (TArrayList<Range>) attrString.attributeMap.get(attribute);
|
||||||
|
if (ranges == null) {
|
||||||
|
return begin;
|
||||||
|
}
|
||||||
|
return runStart(ranges);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRunStart(TSet<? extends Attribute> attributes) {
|
||||||
|
int start = begin;
|
||||||
|
TIterator<? extends Attribute> it = attributes.iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
AttributedCharacterIterator.Attribute attribute = it.next();
|
||||||
|
int newStart = getRunStart(attribute);
|
||||||
|
if (newStart > start) {
|
||||||
|
start = newStart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char last() {
|
||||||
|
if (begin == end) {
|
||||||
|
return DONE;
|
||||||
|
}
|
||||||
|
offset = end - 1;
|
||||||
|
return attrString.text.charAt(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char next() {
|
||||||
|
if (offset >= (end - 1)) {
|
||||||
|
offset = end;
|
||||||
|
return DONE;
|
||||||
|
}
|
||||||
|
return attrString.text.charAt(++offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char previous() {
|
||||||
|
if (offset == begin) {
|
||||||
|
return DONE;
|
||||||
|
}
|
||||||
|
return attrString.text.charAt(--offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char setIndex(int location) {
|
||||||
|
if (location < begin || location > end) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
offset = location;
|
||||||
|
if (offset == end) {
|
||||||
|
return DONE;
|
||||||
|
}
|
||||||
|
return attrString.text.charAt(offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public AttributedString(AttributedCharacterIterator iterator) {
|
||||||
|
if (iterator.getBeginIndex() > iterator.getEndIndex()) {
|
||||||
|
throw new IllegalArgumentException("Invalid substring range");
|
||||||
|
}
|
||||||
|
StringBuilder buffer = new StringBuilder();
|
||||||
|
for (int i = iterator.getBeginIndex(); i < iterator.getEndIndex(); i++) {
|
||||||
|
buffer.append(iterator.current());
|
||||||
|
iterator.next();
|
||||||
|
}
|
||||||
|
text = buffer.toString();
|
||||||
|
TSet<AttributedCharacterIterator.Attribute> attributes = iterator.getAllAttributeKeys();
|
||||||
|
if (attributes == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
attributeMap = new THashMap<>((attributes.size() * 4 / 3) + 1);
|
||||||
|
|
||||||
|
TIterator<Attribute> it = attributes.iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
AttributedCharacterIterator.Attribute attribute = it.next();
|
||||||
|
iterator.setIndex(0);
|
||||||
|
while (iterator.current() != CharacterIterator.DONE) {
|
||||||
|
int start = iterator.getRunStart(attribute);
|
||||||
|
int limit = iterator.getRunLimit(attribute);
|
||||||
|
Object value = iterator.getAttribute(attribute);
|
||||||
|
if (value != null) {
|
||||||
|
addAttribute(attribute, value, start, limit);
|
||||||
|
}
|
||||||
|
iterator.setIndex(limit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private AttributedString(AttributedCharacterIterator iterator, int start, int end, TSet<Attribute> attributes) {
|
||||||
|
if (start < iterator.getBeginIndex() || end > iterator.getEndIndex() || start > end) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attributes == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder buffer = new StringBuilder();
|
||||||
|
iterator.setIndex(start);
|
||||||
|
while (iterator.getIndex() < end) {
|
||||||
|
buffer.append(iterator.current());
|
||||||
|
iterator.next();
|
||||||
|
}
|
||||||
|
text = buffer.toString();
|
||||||
|
attributeMap = new THashMap<>((attributes.size() * 4 / 3) + 1);
|
||||||
|
|
||||||
|
TIterator<Attribute> it = attributes.iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
AttributedCharacterIterator.Attribute attribute = it.next();
|
||||||
|
iterator.setIndex(start);
|
||||||
|
while (iterator.getIndex() < end) {
|
||||||
|
Object value = iterator.getAttribute(attribute);
|
||||||
|
int runStart = iterator.getRunStart(attribute);
|
||||||
|
int limit = iterator.getRunLimit(attribute);
|
||||||
|
if ((value instanceof Annotation && runStart >= start && limit <= end) ||
|
||||||
|
(value != null && !(value instanceof Annotation))) {
|
||||||
|
addAttribute(attribute, value, (runStart < start ? start : runStart) - start, (limit > end ? end
|
||||||
|
: limit) - start);
|
||||||
|
}
|
||||||
|
iterator.setIndex(limit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public AttributedString(AttributedCharacterIterator iterator, int start, int end) {
|
||||||
|
this(iterator, start, end, iterator.getAllAttributeKeys());
|
||||||
|
}
|
||||||
|
|
||||||
|
public AttributedString(AttributedCharacterIterator iterator, int start, int end,
|
||||||
|
AttributedCharacterIterator.Attribute[] attributes) {
|
||||||
|
this(iterator, start, end, new THashSet<>(TArrays.asList(attributes)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public AttributedString(String value) {
|
||||||
|
if (value == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
text = value;
|
||||||
|
attributeMap = new THashMap<>(11);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AttributedString(String value, TMap<? extends AttributedCharacterIterator.Attribute, ?> attributes) {
|
||||||
|
if (value == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
if (value.length() == 0 && !attributes.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("Cannot add attributes to empty string");
|
||||||
|
}
|
||||||
|
text = value;
|
||||||
|
attributeMap = new THashMap<>((attributes.size() * 4 / 3) + 1);
|
||||||
|
TIterator<?> it = attributes.entrySet().iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
TMap.Entry<?, ?> entry = (TMap.Entry<?, ?>) it.next();
|
||||||
|
TArrayList<Range> ranges = new TArrayList<>(1);
|
||||||
|
ranges.add(new Range(0, text.length(), entry.getValue()));
|
||||||
|
attributeMap.put((AttributedCharacterIterator.Attribute) entry.getKey(), ranges);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies a given attribute to this string.
|
||||||
|
*
|
||||||
|
* @param attribute
|
||||||
|
* the attribute that will be applied to this string.
|
||||||
|
* @param value
|
||||||
|
* the value of the attribute that will be applied to this
|
||||||
|
* string.
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
* if the length of this attributed string is 0.
|
||||||
|
* @throws NullPointerException
|
||||||
|
* if {@code attribute} is {@code null}.
|
||||||
|
*/
|
||||||
|
public void addAttribute(AttributedCharacterIterator.Attribute attribute, Object value) {
|
||||||
|
if (null == attribute) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
if (text.length() == 0) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
TList<Range> ranges = attributeMap.get(attribute);
|
||||||
|
if (ranges == null) {
|
||||||
|
ranges = new TArrayList<>(1);
|
||||||
|
attributeMap.put(attribute, ranges);
|
||||||
|
} else {
|
||||||
|
ranges.clear();
|
||||||
|
}
|
||||||
|
ranges.add(new Range(0, text.length(), value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies a given attribute to the given range of this string.
|
||||||
|
*
|
||||||
|
* @param attribute
|
||||||
|
* the attribute that will be applied to this string.
|
||||||
|
* @param value
|
||||||
|
* the value of the attribute that will be applied to this
|
||||||
|
* string.
|
||||||
|
* @param start
|
||||||
|
* the start of the range where the attribute will be applied.
|
||||||
|
* @param end
|
||||||
|
* the end of the range where the attribute will be applied.
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
* if {@code start < 0}, {@code end} is greater than the length
|
||||||
|
* of this string, or if {@code start >= end}.
|
||||||
|
* @throws NullPointerException
|
||||||
|
* if {@code attribute} is {@code null}.
|
||||||
|
*/
|
||||||
|
public void addAttribute(AttributedCharacterIterator.Attribute attribute, Object value, int start, int end) {
|
||||||
|
if (null == attribute) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
if (start < 0 || end > text.length() || start >= end) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TList<Range> ranges = attributeMap.get(attribute);
|
||||||
|
if (ranges == null) {
|
||||||
|
ranges = new TArrayList<>(1);
|
||||||
|
ranges.add(new Range(start, end, value));
|
||||||
|
attributeMap.put(attribute, ranges);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
TListIterator<Range> it = ranges.listIterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
Range range = it.next();
|
||||||
|
if (end <= range.start) {
|
||||||
|
it.previous();
|
||||||
|
break;
|
||||||
|
} else if (start < range.end || (start == range.end && value.equals(range.value))) {
|
||||||
|
Range r1 = null, r3;
|
||||||
|
it.remove();
|
||||||
|
r1 = new Range(range.start, start, range.value);
|
||||||
|
r3 = new Range(end, range.end, range.value);
|
||||||
|
|
||||||
|
while (end > range.end && it.hasNext()) {
|
||||||
|
range = it.next();
|
||||||
|
if (end <= range.end) {
|
||||||
|
if (end > range.start || (end == range.start && value.equals(range.value))) {
|
||||||
|
it.remove();
|
||||||
|
r3 = new Range(end, range.end, range.value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.equals(r1.value)) {
|
||||||
|
if (value.equals(r3.value)) {
|
||||||
|
it.add(new Range(r1.start < start ? r1.start : start, r3.end > end ? r3.end : end, r1.value));
|
||||||
|
} else {
|
||||||
|
it.add(new Range(r1.start < start ? r1.start : start, end, r1.value));
|
||||||
|
if (r3.start < r3.end) {
|
||||||
|
it.add(r3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (value.equals(r3.value)) {
|
||||||
|
if (r1.start < r1.end) {
|
||||||
|
it.add(r1);
|
||||||
|
}
|
||||||
|
it.add(new Range(start, r3.end > end ? r3.end : end, r3.value));
|
||||||
|
} else {
|
||||||
|
if (r1.start < r1.end) {
|
||||||
|
it.add(r1);
|
||||||
|
}
|
||||||
|
it.add(new Range(start, end, value));
|
||||||
|
if (r3.start < r3.end) {
|
||||||
|
it.add(r3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
it.add(new Range(start, end, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies a given set of attributes to the given range of the string.
|
||||||
|
*
|
||||||
|
* @param attributes
|
||||||
|
* the set of attributes that will be applied to this string.
|
||||||
|
* @param start
|
||||||
|
* the start of the range where the attribute will be applied.
|
||||||
|
* @param end
|
||||||
|
* the end of the range where the attribute will be applied.
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
* if {@code start < 0}, {@code end} is greater than the length
|
||||||
|
* of this string, or if {@code start >= end}.
|
||||||
|
*/
|
||||||
|
public void addAttributes(TMap<? extends AttributedCharacterIterator.Attribute, ?> attributes, int start, int end) {
|
||||||
|
TIterator<?> it = attributes.entrySet().iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
TMap.Entry<?, ?> entry = (TMap.Entry<?, ?>) it.next();
|
||||||
|
addAttribute((AttributedCharacterIterator.Attribute) entry.getKey(), entry.getValue(), start, end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an {@code AttributedCharacterIterator} that gives access to the
|
||||||
|
* complete content of this attributed string.
|
||||||
|
*
|
||||||
|
* @return the newly created {@code AttributedCharacterIterator}.
|
||||||
|
*/
|
||||||
|
public AttributedCharacterIterator getIterator() {
|
||||||
|
return new AttributedIterator(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an {@code AttributedCharacterIterator} that gives access to the
|
||||||
|
* complete content of this attributed string. Only attributes contained in
|
||||||
|
* {@code attributes} are available from this iterator if they are defined
|
||||||
|
* for this text.
|
||||||
|
*
|
||||||
|
* @param attributes
|
||||||
|
* the array containing attributes that will be in the new
|
||||||
|
* iterator if they are defined for this text.
|
||||||
|
* @return the newly created {@code AttributedCharacterIterator}.
|
||||||
|
*/
|
||||||
|
public AttributedCharacterIterator getIterator(AttributedCharacterIterator.Attribute[] attributes) {
|
||||||
|
return new AttributedIterator(this, attributes, 0, text.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an {@code AttributedCharacterIterator} that gives access to the
|
||||||
|
* contents of this attributed string starting at index {@code start} up to
|
||||||
|
* index {@code end}. Only attributes contained in {@code attributes} are
|
||||||
|
* available from this iterator if they are defined for this text.
|
||||||
|
*
|
||||||
|
* @param attributes
|
||||||
|
* the array containing attributes that will be in the new
|
||||||
|
* iterator if they are defined for this text.
|
||||||
|
* @param start
|
||||||
|
* the start index of the iterator on the underlying text.
|
||||||
|
* @param end
|
||||||
|
* the end index of the iterator on the underlying text.
|
||||||
|
* @return the newly created {@code AttributedCharacterIterator}.
|
||||||
|
*/
|
||||||
|
public AttributedCharacterIterator getIterator(AttributedCharacterIterator.Attribute[] attributes, int start,
|
||||||
|
int end) {
|
||||||
|
return new AttributedIterator(this, attributes, start, end);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.teavm.classlib.java.text;
|
||||||
|
|
||||||
|
public interface CharacterIterator extends Cloneable {
|
||||||
|
public static final char DONE = '\uffff';
|
||||||
|
|
||||||
|
public Object clone();
|
||||||
|
|
||||||
|
public char current();
|
||||||
|
|
||||||
|
public char first();
|
||||||
|
|
||||||
|
public int getBeginIndex();
|
||||||
|
|
||||||
|
public int getEndIndex();
|
||||||
|
|
||||||
|
public int getIndex();
|
||||||
|
|
||||||
|
public char last();
|
||||||
|
|
||||||
|
public char next();
|
||||||
|
|
||||||
|
public char previous();
|
||||||
|
|
||||||
|
public char setIndex(int location);
|
||||||
|
}
|
|
@ -0,0 +1,283 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.teavm.classlib.java.text;
|
||||||
|
|
||||||
|
import org.teavm.classlib.java.util.*;
|
||||||
|
|
||||||
|
public abstract class DateFormat extends Format {
|
||||||
|
protected TCalendar calendar;
|
||||||
|
//protected NumberFormat numberFormat;
|
||||||
|
public final static int DEFAULT = 2;
|
||||||
|
public final static int FULL = 0;
|
||||||
|
public final static int LONG = 1;
|
||||||
|
public final static int MEDIUM = 2;
|
||||||
|
public final static int SHORT = 3;
|
||||||
|
public final static int ERA_FIELD = 0;
|
||||||
|
public final static int YEAR_FIELD = 1;
|
||||||
|
public final static int MONTH_FIELD = 2;
|
||||||
|
public final static int DATE_FIELD = 3;
|
||||||
|
public final static int HOUR_OF_DAY1_FIELD = 4;
|
||||||
|
public final static int HOUR_OF_DAY0_FIELD = 5;
|
||||||
|
public final static int MINUTE_FIELD = 6;
|
||||||
|
public final static int SECOND_FIELD = 7;
|
||||||
|
public final static int MILLISECOND_FIELD = 8;
|
||||||
|
public final static int DAY_OF_WEEK_FIELD = 9;
|
||||||
|
public final static int DAY_OF_YEAR_FIELD = 10;
|
||||||
|
public final static int DAY_OF_WEEK_IN_MONTH_FIELD = 11;
|
||||||
|
public final static int WEEK_OF_YEAR_FIELD = 12;
|
||||||
|
public final static int WEEK_OF_MONTH_FIELD = 13;
|
||||||
|
public final static int AM_PM_FIELD = 14;
|
||||||
|
public final static int HOUR1_FIELD = 15;
|
||||||
|
public final static int HOUR0_FIELD = 16;
|
||||||
|
public final static int TIMEZONE_FIELD = 17;
|
||||||
|
|
||||||
|
protected DateFormat() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object clone() {
|
||||||
|
DateFormat clone = (DateFormat) super.clone();
|
||||||
|
clone.calendar = (TCalendar) calendar.clone();
|
||||||
|
// TODO: implement
|
||||||
|
//clone.numberFormat = (NumberFormat) numberFormat.clone();
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object object) {
|
||||||
|
/*if (this == object) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(object instanceof DateFormat)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
DateFormat dateFormat = (DateFormat) object;
|
||||||
|
return numberFormat.equals(dateFormat.numberFormat) &&
|
||||||
|
calendar.getFirstDayOfWeek() == dateFormat.calendar.getFirstDayOfWeek() &&
|
||||||
|
calendar.getMinimalDaysInFirstWeek() == dateFormat.calendar.getMinimalDaysInFirstWeek() &&
|
||||||
|
calendar.isLenient() == dateFormat.calendar.isLenient();*/
|
||||||
|
// TODO: implement
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final StringBuffer format(Object object, StringBuffer buffer, FieldPosition field) {
|
||||||
|
if (object instanceof TDate) {
|
||||||
|
return format((TDate) object, buffer, field);
|
||||||
|
}
|
||||||
|
if (object instanceof Number) {
|
||||||
|
return format(new TDate(((Number) object).longValue()), buffer, field);
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public final String format(TDate date) {
|
||||||
|
return format(date, new StringBuffer(), new FieldPosition(0)).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract StringBuffer format(TDate date, StringBuffer buffer, FieldPosition field);
|
||||||
|
|
||||||
|
public static TLocale[] getAvailableLocales() {
|
||||||
|
return TLocale.getAvailableLocales();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TCalendar getCalendar() {
|
||||||
|
return calendar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static DateFormat getDateInstance() {
|
||||||
|
return getDateInstance(DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static DateFormat getDateInstance(int style) {
|
||||||
|
checkDateStyle(style);
|
||||||
|
return getDateInstance(style, TLocale.getDefault());
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static DateFormat getDateInstance(int style, TLocale locale) {
|
||||||
|
/*checkDateStyle(style);
|
||||||
|
com.ibm.icu.text.DateFormat icuFormat = com.ibm.icu.text.DateFormat.getDateInstance(style, locale);
|
||||||
|
return new SimpleDateFormat(locale, (com.ibm.icu.text.SimpleDateFormat) icuFormat);*/
|
||||||
|
// TODO: implement
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static DateFormat getDateTimeInstance() {
|
||||||
|
return getDateTimeInstance(DEFAULT, DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static DateFormat getDateTimeInstance(int dateStyle, int timeStyle) {
|
||||||
|
checkTimeStyle(timeStyle);
|
||||||
|
checkDateStyle(dateStyle);
|
||||||
|
return getDateTimeInstance(dateStyle, timeStyle, TLocale.getDefault());
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static DateFormat getDateTimeInstance(int dateStyle, int timeStyle, TLocale locale) {
|
||||||
|
/*checkTimeStyle(timeStyle);
|
||||||
|
checkDateStyle(dateStyle);
|
||||||
|
com.ibm.icu.text.DateFormat icuFormat = com.ibm.icu.text.DateFormat.getDateTimeInstance(dateStyle, timeStyle,
|
||||||
|
locale);
|
||||||
|
return new SimpleDateFormat(locale, (com.ibm.icu.text.SimpleDateFormat) icuFormat);*/
|
||||||
|
// TODO: implement
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static DateFormat getInstance() {
|
||||||
|
return getDateTimeInstance(SHORT, SHORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*public NumberFormat getNumberFormat() {
|
||||||
|
return numberFormat;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
static String getStyleName(int style) {
|
||||||
|
String styleName;
|
||||||
|
switch (style) {
|
||||||
|
case SHORT:
|
||||||
|
styleName = "SHORT";
|
||||||
|
break;
|
||||||
|
case MEDIUM:
|
||||||
|
styleName = "MEDIUM";
|
||||||
|
break;
|
||||||
|
case LONG:
|
||||||
|
styleName = "LONG";
|
||||||
|
break;
|
||||||
|
case FULL:
|
||||||
|
styleName = "FULL";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
styleName = "";
|
||||||
|
}
|
||||||
|
return styleName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static DateFormat getTimeInstance() {
|
||||||
|
return getTimeInstance(DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static DateFormat getTimeInstance(int style) {
|
||||||
|
checkTimeStyle(style);
|
||||||
|
return getTimeInstance(style, TLocale.getDefault());
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static DateFormat getTimeInstance(int style, TLocale locale) {
|
||||||
|
/*checkTimeStyle(style);
|
||||||
|
com.ibm.icu.text.DateFormat icuFormat = com.ibm.icu.text.DateFormat.getTimeInstance(style, locale);
|
||||||
|
return new SimpleDateFormat(locale, (com.ibm.icu.text.SimpleDateFormat) icuFormat);*/
|
||||||
|
// TODO: implement
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
/*return calendar.getFirstDayOfWeek() + calendar.getMinimalDaysInFirstWeek() +
|
||||||
|
(calendar.isLenient() ? 1231 : 1237) + numberFormat.hashCode();*/
|
||||||
|
// TODO: implement
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLenient() {
|
||||||
|
return calendar.isLenient();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TDate parse(String string) throws ParseException {
|
||||||
|
ParsePosition position = new ParsePosition(0);
|
||||||
|
TDate date = parse(string, position);
|
||||||
|
if (position.getIndex() == 0) {
|
||||||
|
throw new ParseException("Unparseable date" + string, position.getErrorIndex());
|
||||||
|
}
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract TDate parse(String string, ParsePosition position);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object parseObject(String string, ParsePosition position) {
|
||||||
|
return parse(string, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCalendar(TCalendar cal) {
|
||||||
|
calendar = cal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLenient(boolean value) {
|
||||||
|
calendar.setLenient(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*public void setNumberFormat(NumberFormat format) {
|
||||||
|
numberFormat = format;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
public static class Field extends Format.Field {
|
||||||
|
private static THashMap<Integer, Field> table = new THashMap<>();
|
||||||
|
public final static Field ERA = new Field("era", TCalendar.ERA);
|
||||||
|
public final static Field YEAR = new Field("year", TCalendar.YEAR);
|
||||||
|
public final static Field MONTH = new Field("month", TCalendar.MONTH);
|
||||||
|
public final static Field HOUR_OF_DAY0 = new Field("hour of day", TCalendar.HOUR_OF_DAY);
|
||||||
|
public final static Field HOUR_OF_DAY1 = new Field("hour of day 1", -1);
|
||||||
|
public final static Field MINUTE = new Field("minute", TCalendar.MINUTE);
|
||||||
|
public final static Field SECOND = new Field("second", TCalendar.SECOND);
|
||||||
|
public final static Field MILLISECOND = new Field("millisecond", TCalendar.MILLISECOND);
|
||||||
|
public final static Field DAY_OF_WEEK = new Field("day of week", TCalendar.DAY_OF_WEEK);
|
||||||
|
public final static Field DAY_OF_MONTH = new Field("day of month", TCalendar.DAY_OF_MONTH);
|
||||||
|
public final static Field DAY_OF_YEAR = new Field("day of year", TCalendar.DAY_OF_YEAR);
|
||||||
|
public final static Field DAY_OF_WEEK_IN_MONTH = new Field("day of week in month",
|
||||||
|
TCalendar.DAY_OF_WEEK_IN_MONTH);
|
||||||
|
public final static Field WEEK_OF_YEAR = new Field("week of year", TCalendar.WEEK_OF_YEAR);
|
||||||
|
public final static Field WEEK_OF_MONTH = new Field("week of month", TCalendar.WEEK_OF_MONTH);
|
||||||
|
public final static Field AM_PM = new Field("am pm", TCalendar.AM_PM);
|
||||||
|
public final static Field HOUR0 = new Field("hour", TCalendar.HOUR);
|
||||||
|
public final static Field HOUR1 = new Field("hour 1", -1);
|
||||||
|
public final static Field TIME_ZONE = new Field("time zone", -1);
|
||||||
|
private int calendarField = -1;
|
||||||
|
|
||||||
|
protected Field(String fieldName, int calendarField) {
|
||||||
|
super(fieldName);
|
||||||
|
this.calendarField = calendarField;
|
||||||
|
if (calendarField != -1 && table.get(new Integer(calendarField)) == null) {
|
||||||
|
table.put(new Integer(calendarField), this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCalendarField() {
|
||||||
|
return calendarField;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Field ofCalendarField(int calendarField) {
|
||||||
|
if (calendarField < 0 || calendarField >= TCalendar.FIELD_COUNT) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return table.get(new Integer(calendarField));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void checkDateStyle(int style) {
|
||||||
|
if (!(style == SHORT || style == MEDIUM || style == LONG || style == FULL || style == DEFAULT)) {
|
||||||
|
throw new IllegalArgumentException("Illegal date style: " + style);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void checkTimeStyle(int style) {
|
||||||
|
if (!(style == SHORT || style == MEDIUM || style == LONG || style == FULL || style == DEFAULT)) {
|
||||||
|
// text.0F=Illegal time style: {0}
|
||||||
|
throw new IllegalArgumentException("Illegal time style: " + style);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,226 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.teavm.classlib.java.text;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import org.teavm.classlib.impl.unicode.CLDRHelper;
|
||||||
|
import org.teavm.classlib.java.io.TSerializable;
|
||||||
|
import org.teavm.classlib.java.lang.TCloneable;
|
||||||
|
import org.teavm.classlib.java.util.TLocale;
|
||||||
|
|
||||||
|
public class DateFormatSymbols implements TSerializable, TCloneable {
|
||||||
|
private TLocale locale;
|
||||||
|
private String localPatternChars;
|
||||||
|
String[] ampms, eras, months, shortMonths, shortWeekdays, weekdays;
|
||||||
|
String[][] zoneStrings;
|
||||||
|
|
||||||
|
|
||||||
|
public DateFormatSymbols() {
|
||||||
|
this(TLocale.getDefault());
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateFormatSymbols(TLocale locale) {
|
||||||
|
this.locale = locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object clone() {
|
||||||
|
DateFormatSymbols symbols = new DateFormatSymbols(locale);
|
||||||
|
if (ampms != null) {
|
||||||
|
symbols.ampms = Arrays.copyOf(ampms, ampms.length);
|
||||||
|
}
|
||||||
|
if (eras != null) {
|
||||||
|
symbols.eras = Arrays.copyOf(eras, eras.length);
|
||||||
|
}
|
||||||
|
if (months != null) {
|
||||||
|
symbols.months = Arrays.copyOf(months, months.length);
|
||||||
|
}
|
||||||
|
if (shortMonths != null) {
|
||||||
|
symbols.shortMonths = Arrays.copyOf(shortMonths, shortMonths.length);
|
||||||
|
}
|
||||||
|
if (shortWeekdays != null) {
|
||||||
|
symbols.shortWeekdays = Arrays.copyOf(shortWeekdays.clone(), shortWeekdays.length);
|
||||||
|
}
|
||||||
|
if (weekdays != null) {
|
||||||
|
symbols.weekdays = Arrays.copyOf(weekdays, weekdays.length);
|
||||||
|
}
|
||||||
|
if (zoneStrings != null) {
|
||||||
|
symbols.zoneStrings = new String[zoneStrings.length][];
|
||||||
|
for (int i = 0; i < zoneStrings.length; i++) {
|
||||||
|
symbols.zoneStrings[i] = Arrays.copyOf(zoneStrings[i], zoneStrings[i].length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return symbols;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object object) {
|
||||||
|
if (this == object) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(object instanceof DateFormatSymbols)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DateFormatSymbols obj = (DateFormatSymbols) object;
|
||||||
|
if (!locale.equals(obj.locale)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!localPatternChars.equals(obj.localPatternChars)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!Arrays.equals(ampms, obj.ampms)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!Arrays.equals(eras, obj.eras)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!Arrays.equals(months, obj.months)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!Arrays.equals(shortMonths, obj.shortMonths)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!Arrays.equals(shortWeekdays, obj.shortWeekdays)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!Arrays.equals(weekdays, obj.weekdays)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (zoneStrings.length != obj.zoneStrings.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (String[] element : zoneStrings) {
|
||||||
|
if (element.length != element.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (int j = 0; j < element.length; j++) {
|
||||||
|
if (element[j] != element[j] && !(element[j].equals(element[j]))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getAmPmStrings() {
|
||||||
|
return ampms.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getEras() {
|
||||||
|
if (eras == null) {
|
||||||
|
eras = CLDRHelper.resolveEras(CLDRHelper.getCode(locale.getLanguage(), locale.getCountry()));
|
||||||
|
}
|
||||||
|
return eras.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLocalPatternChars() {
|
||||||
|
return localPatternChars;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getMonths() {
|
||||||
|
return months.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getShortMonths() {
|
||||||
|
return shortMonths.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getShortWeekdays() {
|
||||||
|
return shortWeekdays.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getWeekdays() {
|
||||||
|
return weekdays.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[][] getZoneStrings() {
|
||||||
|
String[][] clone = new String[zoneStrings.length][];
|
||||||
|
for (int i = zoneStrings.length; --i >= 0;) {
|
||||||
|
clone[i] = zoneStrings[i].clone();
|
||||||
|
}
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int hashCode;
|
||||||
|
hashCode = localPatternChars.hashCode();
|
||||||
|
for (String element : ampms) {
|
||||||
|
hashCode += element.hashCode();
|
||||||
|
}
|
||||||
|
for (String element : eras) {
|
||||||
|
hashCode += element.hashCode();
|
||||||
|
}
|
||||||
|
for (String element : months) {
|
||||||
|
hashCode += element.hashCode();
|
||||||
|
}
|
||||||
|
for (String element : shortMonths) {
|
||||||
|
hashCode += element.hashCode();
|
||||||
|
}
|
||||||
|
for (String element : shortWeekdays) {
|
||||||
|
hashCode += element.hashCode();
|
||||||
|
}
|
||||||
|
for (String element : weekdays) {
|
||||||
|
hashCode += element.hashCode();
|
||||||
|
}
|
||||||
|
for (String[] element : zoneStrings) {
|
||||||
|
for (int j = 0; j < element.length; j++) {
|
||||||
|
if (element[j] != null) {
|
||||||
|
hashCode += element[j].hashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAmPmStrings(String[] data) {
|
||||||
|
ampms = data.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEras(String[] data) {
|
||||||
|
eras = data.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocalPatternChars(String data) {
|
||||||
|
if (data == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
localPatternChars = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMonths(String[] data) {
|
||||||
|
months = data.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setShortMonths(String[] data) {
|
||||||
|
shortMonths = data.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setShortWeekdays(String[] data) {
|
||||||
|
shortWeekdays = data.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWeekdays(String[] data) {
|
||||||
|
weekdays = data.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setZoneStrings(String[][] data) {
|
||||||
|
zoneStrings = data.clone();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.teavm.classlib.java.text;
|
||||||
|
|
||||||
|
public class FieldPosition {
|
||||||
|
private int myField, beginIndex, endIndex;
|
||||||
|
private Format.Field myAttribute;
|
||||||
|
|
||||||
|
public FieldPosition(int field) {
|
||||||
|
myField = field;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldPosition(Format.Field attribute) {
|
||||||
|
myAttribute = attribute;
|
||||||
|
myField = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldPosition(Format.Field attribute, int field) {
|
||||||
|
myAttribute = attribute;
|
||||||
|
myField = field;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
beginIndex = endIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object object) {
|
||||||
|
if (!(object instanceof FieldPosition)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
FieldPosition pos = (FieldPosition) object;
|
||||||
|
return myField == pos.myField && myAttribute == pos.myAttribute && beginIndex == pos.beginIndex &&
|
||||||
|
endIndex == pos.endIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBeginIndex() {
|
||||||
|
return beginIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEndIndex() {
|
||||||
|
return endIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getField() {
|
||||||
|
return myField;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Format.Field getFieldAttribute() {
|
||||||
|
return myAttribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int attributeHash = (myAttribute == null) ? 0 : myAttribute.hashCode();
|
||||||
|
return attributeHash + myField * 10 + beginIndex * 100 + endIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBeginIndex(int index) {
|
||||||
|
beginIndex = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEndIndex(int index) {
|
||||||
|
endIndex = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return getClass().getName() + "[attribute=" + myAttribute + ", field=" + myField + ", beginIndex=" +
|
||||||
|
beginIndex + ", endIndex=" + endIndex + "]";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,137 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.teavm.classlib.java.text;
|
||||||
|
|
||||||
|
import org.teavm.classlib.java.io.TSerializable;
|
||||||
|
import org.teavm.classlib.java.lang.TCloneable;
|
||||||
|
|
||||||
|
public abstract class Format implements TSerializable, TCloneable {
|
||||||
|
public Format() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object clone() {
|
||||||
|
try {
|
||||||
|
return super.clone();
|
||||||
|
} catch (CloneNotSupportedException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String convertPattern(String template, String fromChars, String toChars, boolean check) {
|
||||||
|
if (!check && fromChars.equals(toChars)) {
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
boolean quote = false;
|
||||||
|
StringBuilder output = new StringBuilder();
|
||||||
|
int length = template.length();
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
int index;
|
||||||
|
char next = template.charAt(i);
|
||||||
|
if (next == '\'') {
|
||||||
|
quote = !quote;
|
||||||
|
}
|
||||||
|
if (!quote && (index = fromChars.indexOf(next)) != -1) {
|
||||||
|
output.append(toChars.charAt(index));
|
||||||
|
} else if (check && !quote && ((next >= 'a' && next <= 'z') || (next >= 'A' && next <= 'Z'))) {
|
||||||
|
throw new IllegalArgumentException("Invalid pattern char" + next + " in " + template);
|
||||||
|
} else {
|
||||||
|
output.append(next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (quote) {
|
||||||
|
throw new IllegalArgumentException("Unterminated quote");
|
||||||
|
}
|
||||||
|
return output.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public final String format(Object object) {
|
||||||
|
return format(object, new StringBuffer(), new FieldPosition(0)).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract StringBuffer format(Object object, StringBuffer buffer, FieldPosition field);
|
||||||
|
|
||||||
|
public AttributedCharacterIterator formatToCharacterIterator(Object object) {
|
||||||
|
return new AttributedString(format(object)).getIterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object parseObject(String string) throws ParseException {
|
||||||
|
ParsePosition position = new ParsePosition(0);
|
||||||
|
Object result = parseObject(string, position);
|
||||||
|
if (position.getIndex() == 0) {
|
||||||
|
throw new ParseException("Format.parseObject(String) parse failure", position.getErrorIndex());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract Object parseObject(String string, ParsePosition position);
|
||||||
|
|
||||||
|
static boolean upTo(String string, ParsePosition position, StringBuffer buffer, char stop) {
|
||||||
|
int index = position.getIndex(), length = string.length();
|
||||||
|
boolean lastQuote = false, quote = false;
|
||||||
|
while (index < length) {
|
||||||
|
char ch = string.charAt(index++);
|
||||||
|
if (ch == '\'') {
|
||||||
|
if (lastQuote) {
|
||||||
|
buffer.append('\'');
|
||||||
|
}
|
||||||
|
quote = !quote;
|
||||||
|
lastQuote = true;
|
||||||
|
} else if (ch == stop && !quote) {
|
||||||
|
position.setIndex(index);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
lastQuote = false;
|
||||||
|
buffer.append(ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
position.setIndex(index);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean upToWithQuotes(String string, ParsePosition position, StringBuffer buffer, char stop, char start) {
|
||||||
|
int index = position.getIndex(), length = string.length(), count = 1;
|
||||||
|
boolean quote = false;
|
||||||
|
while (index < length) {
|
||||||
|
char ch = string.charAt(index++);
|
||||||
|
if (ch == '\'') {
|
||||||
|
quote = !quote;
|
||||||
|
}
|
||||||
|
if (!quote) {
|
||||||
|
if (ch == stop) {
|
||||||
|
count--;
|
||||||
|
}
|
||||||
|
if (count == 0) {
|
||||||
|
position.setIndex(index);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (ch == start) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer.append(ch);
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Unmatched braces in the pattern");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Field extends AttributedCharacterIterator.Attribute {
|
||||||
|
protected Field(String fieldName) {
|
||||||
|
super(fieldName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.teavm.classlib.java.text;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thrown when the string being parsed is not in the correct form.
|
||||||
|
*/
|
||||||
|
public class ParseException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 2703218443322787634L;
|
||||||
|
|
||||||
|
private int errorOffset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new instance of this class with its stack trace, detail
|
||||||
|
* message and the location of the error filled in.
|
||||||
|
*
|
||||||
|
* @param detailMessage
|
||||||
|
* the detail message for this exception.
|
||||||
|
* @param location
|
||||||
|
* the index at which the parse exception occurred.
|
||||||
|
*/
|
||||||
|
public ParseException(String detailMessage, int location) {
|
||||||
|
super(detailMessage);
|
||||||
|
errorOffset = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the index at which this parse exception occurred.
|
||||||
|
*
|
||||||
|
* @return the location of this exception in the parsed string.
|
||||||
|
*/
|
||||||
|
public int getErrorOffset() {
|
||||||
|
return errorOffset;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.teavm.classlib.java.text;
|
||||||
|
|
||||||
|
public class ParsePosition {
|
||||||
|
|
||||||
|
private int currentPosition, errorIndex = -1;
|
||||||
|
|
||||||
|
public ParsePosition(int index) {
|
||||||
|
currentPosition = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object object) {
|
||||||
|
if (!(object instanceof ParsePosition)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ParsePosition pos = (ParsePosition) object;
|
||||||
|
return currentPosition == pos.currentPosition && errorIndex == pos.errorIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getErrorIndex() {
|
||||||
|
return errorIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIndex() {
|
||||||
|
return currentPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return currentPosition + errorIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setErrorIndex(int index) {
|
||||||
|
errorIndex = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIndex(int index) {
|
||||||
|
currentPosition = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return getClass().getName() + "[index=" + currentPosition + ", errorIndex=" + errorIndex + "]";
|
||||||
|
}
|
||||||
|
}
|
|
@ -100,7 +100,7 @@ public class LocaleSettingsNativeGenerator implements Generator {
|
||||||
if (localeName.startsWith("/")) {
|
if (localeName.startsWith("/")) {
|
||||||
localeName = localeName.substring(1);
|
localeName = localeName.substring(1);
|
||||||
}
|
}
|
||||||
if (!availableLocales.contains(localeName)) {
|
if (!localeName.equals("root") && !availableLocales.contains(localeName)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
LocaleInfo localeInfo = knownLocales.get(localeName);
|
LocaleInfo localeInfo = knownLocales.get(localeName);
|
||||||
|
@ -115,6 +115,9 @@ public class LocaleSettingsNativeGenerator implements Generator {
|
||||||
case "territories.json":
|
case "territories.json":
|
||||||
readCountries(localeName, localeInfo, input);
|
readCountries(localeName, localeInfo, input);
|
||||||
break;
|
break;
|
||||||
|
case "ca-gregorian.json":
|
||||||
|
readEras(localeName, localeInfo, input);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -146,6 +149,16 @@ public class LocaleSettingsNativeGenerator implements Generator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void readEras(String localeCode, LocaleInfo locale, InputStream input) {
|
||||||
|
JsonObject root = (JsonObject)new JsonParser().parse(new InputStreamReader(input));
|
||||||
|
JsonObject erasJson = root.get("main").getAsJsonObject().get(localeCode).getAsJsonObject()
|
||||||
|
.get("calendars").getAsJsonObject().get("gregorian").getAsJsonObject()
|
||||||
|
.get("eras").getAsJsonObject().get("eraNames").getAsJsonObject();
|
||||||
|
String am = erasJson.get("0").getAsString();
|
||||||
|
String pm = erasJson.get("1").getAsString();
|
||||||
|
locale.eras = new String[] { am, pm };
|
||||||
|
}
|
||||||
|
|
||||||
private void readWeekData(InputStream input) {
|
private void readWeekData(InputStream input) {
|
||||||
JsonObject root = (JsonObject)new JsonParser().parse(new InputStreamReader(input));
|
JsonObject root = (JsonObject)new JsonParser().parse(new InputStreamReader(input));
|
||||||
JsonObject weekJson = root.get("supplemental").getAsJsonObject().get("weekData").getAsJsonObject();
|
JsonObject weekJson = root.get("supplemental").getAsJsonObject().get("weekData").getAsJsonObject();
|
||||||
|
@ -338,5 +351,6 @@ public class LocaleSettingsNativeGenerator implements Generator {
|
||||||
static class LocaleInfo {
|
static class LocaleInfo {
|
||||||
Map<String, String> languages = new LinkedHashMap<>();
|
Map<String, String> languages = new LinkedHashMap<>();
|
||||||
Map<String, String> territories = new LinkedHashMap<>();
|
Map<String, String> territories = new LinkedHashMap<>();
|
||||||
|
String[] eras;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,4 +181,9 @@ public class THashSet<E> extends TAbstractSet<E> implements TCloneable, TSeriali
|
||||||
THashMap<E, THashSet<E>> createBackingMap(int capacity, float loadFactor) {
|
THashMap<E, THashSet<E>> createBackingMap(int capacity, float loadFactor) {
|
||||||
return new THashMap<>(capacity, loadFactor);
|
return new THashMap<>(capacity, loadFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object clone() {
|
||||||
|
return new THashSet<>(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user