ICU-3064 code review changes
X-SVN-Rev: 12977
This commit is contained in:
parent
820be87436
commit
db3dc35976
@ -5,8 +5,8 @@
|
|||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
*
|
*
|
||||||
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/test/stringprep/NFS4StringPrep.java,v $
|
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/test/stringprep/NFS4StringPrep.java,v $
|
||||||
* $Date: 2003/08/27 21:19:01 $
|
* $Date: 2003/08/28 23:03:06 $
|
||||||
* $Revision: 1.5 $
|
* $Revision: 1.6 $
|
||||||
*
|
*
|
||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
*/
|
*/
|
||||||
@ -29,13 +29,7 @@ import com.ibm.icu.text.UCharacterIterator;
|
|||||||
* for testing.
|
* for testing.
|
||||||
*/
|
*/
|
||||||
public final class NFS4StringPrep {
|
public final class NFS4StringPrep {
|
||||||
private static final String[] NFS4DataFileNames ={
|
|
||||||
"nfscss.spp",
|
|
||||||
"nfscsi.spp",
|
|
||||||
"nfscis.spp",
|
|
||||||
"nfsmxp.spp",
|
|
||||||
"nfsmxs.spp"
|
|
||||||
};
|
|
||||||
private StringPrep nfscss = null;
|
private StringPrep nfscss = null;
|
||||||
private StringPrep nfscsi = null;
|
private StringPrep nfscsi = null;
|
||||||
private StringPrep nfscis = null;
|
private StringPrep nfscis = null;
|
||||||
@ -47,25 +41,24 @@ public final class NFS4StringPrep {
|
|||||||
|
|
||||||
private NFS4StringPrep (){
|
private NFS4StringPrep (){
|
||||||
try{
|
try{
|
||||||
|
InputStream nfscsiFile = TestUtil.getDataStream("nfscsi.spp");
|
||||||
InputStream nfscssFile = TestUtil.getDataStream(NFS4DataFileNames[0]);
|
nfscsi = new StringPrep(nfscsiFile);
|
||||||
nfscss = StringPrep.getInstance(nfscssFile);
|
nfscsiFile.close();
|
||||||
|
|
||||||
|
InputStream nfscssFile = TestUtil.getDataStream("nfscss.spp");
|
||||||
|
nfscss = new StringPrep(nfscssFile);
|
||||||
nfscssFile.close();
|
nfscssFile.close();
|
||||||
|
|
||||||
InputStream nfscsiFile = TestUtil.getDataStream(NFS4DataFileNames[1]);
|
InputStream nfscisFile = TestUtil.getDataStream("nfscis.spp");
|
||||||
nfscsi = StringPrep.getInstance(nfscsiFile);
|
nfscis = new StringPrep(nfscisFile);
|
||||||
nfscsiFile.close();
|
nfscisFile.close();
|
||||||
|
|
||||||
InputStream nfscisFile = TestUtil.getDataStream(NFS4DataFileNames[2]);
|
InputStream nfsmxpFile = TestUtil.getDataStream("nfsmxp.spp");
|
||||||
nfscis = StringPrep.getInstance(nfscisFile);
|
nfsmxp = new StringPrep(nfsmxpFile);
|
||||||
nfscsiFile.close();
|
nfsmxpFile.close();
|
||||||
|
|
||||||
InputStream nfsmxpFile = TestUtil.getDataStream(NFS4DataFileNames[3]);
|
InputStream nfsmxsFile = TestUtil.getDataStream("nfsmxs.spp");
|
||||||
nfsmxp = StringPrep.getInstance(nfsmxpFile);
|
nfsmxs = new StringPrep(nfsmxsFile);
|
||||||
nfscsiFile.close();
|
|
||||||
|
|
||||||
InputStream nfsmxsFile = TestUtil.getDataStream(NFS4DataFileNames[4]);
|
|
||||||
nfsmxs = StringPrep.getInstance(nfsmxsFile);
|
|
||||||
nfsmxsFile.close();
|
nfsmxsFile.close();
|
||||||
}catch(IOException e){
|
}catch(IOException e){
|
||||||
throw new RuntimeException(e.toString());
|
throw new RuntimeException(e.toString());
|
||||||
@ -83,12 +76,12 @@ public final class NFS4StringPrep {
|
|||||||
return out.toString().getBytes("UTF-8");
|
return out.toString().getBytes("UTF-8");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] cs_prepare(byte[] src, boolean caseInsensitive)
|
public static byte[] cs_prepare(byte[] src, boolean isCaseSensitive)
|
||||||
throws StringPrepParseException, UnsupportedEncodingException{
|
throws StringPrepParseException, UnsupportedEncodingException{
|
||||||
if(caseInsensitive){
|
if(isCaseSensitive == true ){
|
||||||
return prepare(src, prep.nfscsi);
|
|
||||||
}else{
|
|
||||||
return prepare(src, prep.nfscss);
|
return prepare(src, prep.nfscss);
|
||||||
|
}else{
|
||||||
|
return prepare(src, prep.nfscsi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
*
|
*
|
||||||
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/test/stringprep/TestAll.java,v $
|
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/test/stringprep/TestAll.java,v $
|
||||||
* $Date: 2003/08/21 23:42:25 $
|
* $Date: 2003/08/28 23:03:06 $
|
||||||
* $Revision: 1.1 $
|
* $Revision: 1.2 $
|
||||||
*
|
*
|
||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
*/
|
*/
|
||||||
@ -28,12 +28,13 @@ public class TestAll extends TestGroup {
|
|||||||
|
|
||||||
public TestAll() {
|
public TestAll() {
|
||||||
super(
|
super(
|
||||||
new String[] {
|
new String[] {
|
||||||
"TestIDNA",
|
"TestIDNA",
|
||||||
"TestStringPrep",
|
"TestStringPrep",
|
||||||
"TestIDNARef"
|
"TestIDNARef"
|
||||||
},
|
},
|
||||||
"StringPrep and IDNA test");
|
"StringPrep and IDNA test"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String CLASS_TARGET_NAME = "StringPrep";
|
public static final String CLASS_TARGET_NAME = "StringPrep";
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
*
|
*
|
||||||
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/test/stringprep/TestIDNA.java,v $
|
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/test/stringprep/TestIDNA.java,v $
|
||||||
* $Date: 2003/08/27 21:19:00 $
|
* $Date: 2003/08/28 23:03:06 $
|
||||||
* $Revision: 1.3 $
|
* $Revision: 1.4 $
|
||||||
*
|
*
|
||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
*/
|
*/
|
||||||
@ -295,7 +295,7 @@ public class TestIDNA extends TestFmwk {
|
|||||||
}
|
}
|
||||||
public void TestNamePrepConformance() throws Exception{
|
public void TestNamePrepConformance() throws Exception{
|
||||||
InputStream stream = LocaleUtility.getImplDataResourceAsStream("uidna.spp");
|
InputStream stream = LocaleUtility.getImplDataResourceAsStream("uidna.spp");
|
||||||
StringPrep namePrep = StringPrep.getInstance(stream);
|
StringPrep namePrep = new StringPrep(stream);
|
||||||
for(int i=0; i<TestData.conformanceTestCases.length;i++){
|
for(int i=0; i<TestData.conformanceTestCases.length;i++){
|
||||||
TestData.ConformanceTestCase testCase = TestData.conformanceTestCases[i];
|
TestData.ConformanceTestCase testCase = TestData.conformanceTestCases[i];
|
||||||
UCharacterIterator iter = UCharacterIterator.getInstance(testCase.input);
|
UCharacterIterator iter = UCharacterIterator.getInstance(testCase.input);
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
*
|
*
|
||||||
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/test/stringprep/TestStringPrep.java,v $
|
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/test/stringprep/TestStringPrep.java,v $
|
||||||
* $Date: 2003/08/27 03:08:29 $
|
* $Date: 2003/08/28 23:03:06 $
|
||||||
* $Revision: 1.2 $
|
* $Revision: 1.3 $
|
||||||
*
|
*
|
||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
*/
|
*/
|
||||||
@ -177,7 +177,7 @@ public class TestStringPrep extends TestFmwk {
|
|||||||
// test case insensitive string
|
// test case insensitive string
|
||||||
try{
|
try{
|
||||||
src = "THISISATEST";
|
src = "THISISATEST";
|
||||||
byte[] dest = NFS4StringPrep.cs_prepare(src.getBytes("UTF-8"), true);
|
byte[] dest = NFS4StringPrep.cs_prepare(src.getBytes("UTF-8"), false);
|
||||||
String destStr = new String(dest, "UTF-8");
|
String destStr = new String(dest, "UTF-8");
|
||||||
if(!src.toLowerCase().equals(destStr)){
|
if(!src.toLowerCase().equals(destStr)){
|
||||||
errln("Did not get expected output. Expected: "+ prettify(src)+
|
errln("Did not get expected output. Expected: "+ prettify(src)+
|
||||||
@ -186,6 +186,18 @@ public class TestStringPrep extends TestFmwk {
|
|||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
errln("Got unexpected exception: " + e.toString());
|
errln("Got unexpected exception: " + e.toString());
|
||||||
}
|
}
|
||||||
|
// test case sensitive string
|
||||||
|
try{
|
||||||
|
src = "THISISATEST";
|
||||||
|
byte[] dest = NFS4StringPrep.cs_prepare(src.getBytes("UTF-8"), true);
|
||||||
|
String destStr = new String(dest, "UTF-8");
|
||||||
|
if(!src.equals(destStr)){
|
||||||
|
errln("Did not get expected output. Expected: "+ prettify(src)+
|
||||||
|
" Got: " + prettify(destStr));
|
||||||
|
}
|
||||||
|
}catch(Exception e){
|
||||||
|
errln("Got unexpected exception: " + e.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
* others. All Rights Reserved. *
|
* others. All Rights Reserved. *
|
||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/text/IDNA.java,v $
|
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/text/IDNA.java,v $
|
||||||
* $Date: 2003/08/27 21:12:04 $
|
* $Date: 2003/08/28 23:03:47 $
|
||||||
* $Revision: 1.1 $
|
* $Revision: 1.2 $
|
||||||
*
|
*
|
||||||
*****************************************************************************************
|
*****************************************************************************************
|
||||||
*/
|
*/
|
||||||
@ -18,17 +18,16 @@ import com.ibm.icu.impl.LocaleUtility;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* IDNA API implements the IDNA protocol as defined in the IDNA draft
|
* IDNA API implements the IDNA protocol as defined in the <a href="(http://www.ietf.org/rfc/rfc3490.txt">IDNA RFC</a>.
|
||||||
* (http://www.ietf.org/rfc/rfc3490.txt).
|
|
||||||
* The draft defines 2 operations: ToASCII and ToUnicode. Domain labels
|
* The draft defines 2 operations: ToASCII and ToUnicode. Domain labels
|
||||||
* containing non-ASCII code points are required to be processed by
|
* containing non-ASCII code points are required to be processed by
|
||||||
* ToASCII operation before passing it to resolver libraries. Domain names
|
* ToASCII operation before passing it to resolver libraries. Domain names
|
||||||
* that are obtained from resolver libraries are required to be processed by
|
* that are obtained from resolver libraries are required to be processed by
|
||||||
* ToUnicode operation before displaying the domain name to the user.
|
* ToUnicode operation before displaying the domain name to the user.
|
||||||
* IDNA requires that implementations process input strings with Nameprep
|
* IDNA requires that implementations process input strings with
|
||||||
* (http://www.ietf.org/rfc/rfc3491.txt),
|
* <a href="http://www.ietf.org/rfc/rfc3491.txt">Nameprep</a>,
|
||||||
* which is a profile of Stringprep (http://www.ietf.org/rfc/rfc3454.txt),
|
* which is a profile of <a href="http://www.ietf.org/rfc/rfc3454.txt">Stringprep</a> ,
|
||||||
* and then with Punycode (http://www.ietf.org/rfc/rfc3492.txt).
|
* and then with <a href="http://www.ietf.org/rfc/rfc3492.txt">Punycode</a>.
|
||||||
* Implementations of IDNA MUST fully implement Nameprep and Punycode;
|
* Implementations of IDNA MUST fully implement Nameprep and Punycode;
|
||||||
* neither Nameprep nor Punycode are optional.
|
* neither Nameprep nor Punycode are optional.
|
||||||
* The input and output of ToASCII and ToUnicode operations are Unicode
|
* The input and output of ToASCII and ToUnicode operations are Unicode
|
||||||
@ -89,7 +88,7 @@ public final class IDNA {
|
|||||||
private IDNA(){
|
private IDNA(){
|
||||||
try{
|
try{
|
||||||
InputStream stream = LocaleUtility.getImplDataResourceAsStream("uidna.spp");
|
InputStream stream = LocaleUtility.getImplDataResourceAsStream("uidna.spp");
|
||||||
namePrep = StringPrep.getInstance(stream);
|
namePrep = new StringPrep(stream);
|
||||||
stream.close();
|
stream.close();
|
||||||
}catch (IOException e){
|
}catch (IOException e){
|
||||||
throw new RuntimeException(e.toString());
|
throw new RuntimeException(e.toString());
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
* others. All Rights Reserved. *
|
* others. All Rights Reserved. *
|
||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/text/StringPrep.java,v $
|
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/text/StringPrep.java,v $
|
||||||
* $Date: 2003/08/27 21:12:04 $
|
* $Date: 2003/08/28 23:03:47 $
|
||||||
* $Revision: 1.1 $
|
* $Revision: 1.2 $
|
||||||
*
|
*
|
||||||
*****************************************************************************************
|
*****************************************************************************************
|
||||||
*/
|
*/
|
||||||
@ -24,7 +24,8 @@ import com.ibm.icu.lang.UCharacter;
|
|||||||
import com.ibm.icu.lang.UCharacterDirection;
|
import com.ibm.icu.lang.UCharacterDirection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* StringPrep API implements the StingPrep framework as described by RFC 3454.
|
* StringPrep API implements the StingPrep framework as described by
|
||||||
|
* <a href="http://www.ietf.org/rfc/rfc3454.txt">RFC 3454</a>.
|
||||||
* StringPrep prepares Unicode strings for use in network protocols.
|
* StringPrep prepares Unicode strings for use in network protocols.
|
||||||
* Profiles of StingPrep are set of rules and data according to which the
|
* Profiles of StingPrep are set of rules and data according to which the
|
||||||
* Unicode Strings are prepared. Each profiles contains tables which describe
|
* Unicode Strings are prepared. Each profiles contains tables which describe
|
||||||
@ -104,7 +105,7 @@ public final class StringPrep {
|
|||||||
|
|
||||||
/* Wrappers for Trie implementations */
|
/* Wrappers for Trie implementations */
|
||||||
private static final class StringPrepTrieImpl implements Trie.DataManipulate{
|
private static final class StringPrepTrieImpl implements Trie.DataManipulate{
|
||||||
static CharTrie sprepTrie = null;
|
private CharTrie sprepTrie = null;
|
||||||
/**
|
/**
|
||||||
* Called by com.ibm.icu.util.Trie to extract from a lead surrogate's
|
* Called by com.ibm.icu.util.Trie to extract from a lead surrogate's
|
||||||
* data the index array offset of the indexes for that lead surrogate.
|
* data the index array offset of the indexes for that lead surrogate.
|
||||||
@ -117,23 +118,30 @@ public final class StringPrep {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static StringPrepTrieImpl sprepTrieImpl;
|
// CharTrie implmentation for reading the trie data
|
||||||
private static int[] indexes;
|
private StringPrepTrieImpl sprepTrieImpl;
|
||||||
private static char[] mappingData;
|
// Indexes read from the data file
|
||||||
private static byte[] formatVersion;
|
private int[] indexes;
|
||||||
|
// mapping data read from the data file
|
||||||
|
private char[] mappingData;
|
||||||
|
// format version of the data file
|
||||||
|
private byte[] formatVersion;
|
||||||
|
// the version of Unicode supported by the data file
|
||||||
|
private VersionInfo unicodeVersion;
|
||||||
|
// the Unicode version of last entry in the
|
||||||
|
// NormalizationCorrections.txt file if normalization
|
||||||
|
// is turned on
|
||||||
|
private VersionInfo normVersion;
|
||||||
|
// Option to turn on Normalization
|
||||||
|
private boolean doNFKC;
|
||||||
|
// Option to turn on checking for BiDi rules
|
||||||
|
private boolean checkBiDi;
|
||||||
|
|
||||||
|
|
||||||
private char getCodePointValue(int ch){
|
private char getCodePointValue(int ch){
|
||||||
return StringPrepTrieImpl.sprepTrie.getCodePointValue(ch);
|
return sprepTrieImpl.sprepTrie.getCodePointValue(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
//protected
|
|
||||||
private boolean doNFKC = false;
|
|
||||||
private boolean checkBiDi = false;
|
|
||||||
|
|
||||||
private VersionInfo unicodeVersion;
|
|
||||||
private VersionInfo normVersion;
|
|
||||||
|
|
||||||
|
|
||||||
private static VersionInfo getVersionInfo(int comp){
|
private static VersionInfo getVersionInfo(int comp){
|
||||||
int micro = comp & 0xFF;
|
int micro = comp & 0xFF;
|
||||||
int milli =(comp >> 8) & 0xFF;
|
int milli =(comp >> 8) & 0xFF;
|
||||||
@ -147,8 +155,17 @@ public final class StringPrep {
|
|||||||
}
|
}
|
||||||
return VersionInfo.getInstance((int)version[0],(int) version[1],(int) version[2],(int) version[3]);
|
return VersionInfo.getInstance((int)version[0],(int) version[1],(int) version[2],(int) version[3]);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
private StringPrep(InputStream inputStream) throws IOException{
|
* Creates an StringPrep object after reading the input stream.
|
||||||
|
* The object does not hold a reference to the input steam, so the stream can be
|
||||||
|
* closed after the method returns.
|
||||||
|
*
|
||||||
|
* @param inputStream The stream for reading the StringPrep profile binary
|
||||||
|
* @return StringPrep object created from the input stream
|
||||||
|
* @throws IOException
|
||||||
|
* @draft ICU 2.8
|
||||||
|
*/
|
||||||
|
public StringPrep(InputStream inputStream) throws IOException{
|
||||||
|
|
||||||
BufferedInputStream b = new BufferedInputStream(inputStream,DATA_BUFFER_SIZE);
|
BufferedInputStream b = new BufferedInputStream(inputStream,DATA_BUFFER_SIZE);
|
||||||
|
|
||||||
@ -159,14 +176,15 @@ public final class StringPrep {
|
|||||||
|
|
||||||
byte[] sprepBytes = new byte[indexes[INDEX_TRIE_SIZE]];
|
byte[] sprepBytes = new byte[indexes[INDEX_TRIE_SIZE]];
|
||||||
|
|
||||||
sprepTrieImpl = new StringPrepTrieImpl();
|
|
||||||
//indexes[INDEX_MAPPING_DATA_SIZE] store the size of mappingData in bytes
|
//indexes[INDEX_MAPPING_DATA_SIZE] store the size of mappingData in bytes
|
||||||
mappingData = new char[indexes[INDEX_MAPPING_DATA_SIZE]/2];
|
mappingData = new char[indexes[INDEX_MAPPING_DATA_SIZE]/2];
|
||||||
// load the rest of the data data and initialize the data members
|
// load the rest of the data data and initialize the data members
|
||||||
reader.read(sprepBytes,mappingData);
|
reader.read(sprepBytes,mappingData);
|
||||||
|
|
||||||
StringPrepTrieImpl.sprepTrie = new CharTrie( new ByteArrayInputStream(sprepBytes),sprepTrieImpl );
|
sprepTrieImpl = new StringPrepTrieImpl();
|
||||||
|
sprepTrieImpl.sprepTrie = new CharTrie( new ByteArrayInputStream(sprepBytes),sprepTrieImpl );
|
||||||
|
|
||||||
// get the data format version
|
// get the data format version
|
||||||
formatVersion = reader.getDataFormatVersion();
|
formatVersion = reader.getDataFormatVersion();
|
||||||
|
|
||||||
@ -180,38 +198,24 @@ public final class StringPrep {
|
|||||||
}
|
}
|
||||||
b.close();
|
b.close();
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Returns the StringPrep instance created after reading the input stream.
|
private static final class Values{
|
||||||
* The object does not hold a reference to the input steam, so the stream can be
|
|
||||||
* closed after the method returns.
|
|
||||||
*
|
|
||||||
* @param inputStream The stream for reading the StringPrep profile binary
|
|
||||||
* @return StringPrep object created from the input stream
|
|
||||||
* @throws IOException
|
|
||||||
* @draft ICU 2.8
|
|
||||||
*/
|
|
||||||
public static final StringPrep getInstance(InputStream inputStream)
|
|
||||||
throws IOException{
|
|
||||||
|
|
||||||
StringPrep prep = null;
|
|
||||||
// load the file and create the object
|
|
||||||
prep = new StringPrep(inputStream);
|
|
||||||
|
|
||||||
return prep;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class Values{
|
|
||||||
boolean isIndex;
|
boolean isIndex;
|
||||||
int value;
|
int value;
|
||||||
int type;
|
int type;
|
||||||
|
public void reset(){
|
||||||
|
isIndex = false;
|
||||||
|
value = 0;
|
||||||
|
type = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final void getValues(char trieWord,Values values){
|
private static final void getValues(char trieWord,Values values){
|
||||||
|
values.reset();
|
||||||
if(trieWord == 0){
|
if(trieWord == 0){
|
||||||
/*
|
/*
|
||||||
* Initial value stored in the mapping table
|
* Initial value stored in the mapping table
|
||||||
* just return USPREP_TYPE_LIMIT .. so that
|
* just return TYPE_LIMIT .. so that
|
||||||
* the source codepoint is copied to the destination
|
* the source codepoint is copied to the destination
|
||||||
*/
|
*/
|
||||||
values.type = TYPE_LIMIT;
|
values.type = TYPE_LIMIT;
|
||||||
|
Loading…
Reference in New Issue
Block a user