зеркало из https://github.com/mozilla/gecko-dev.git
Bug 348710 - Fix array handling bug. Add support for sized strings. Update unit tests to test array parameters. XULRunner only.
This commit is contained in:
Родитель
d1a5b3317d
Коммит
e608d6be61
|
@ -888,6 +888,67 @@ SetupParams(JNIEnv *env, const jobject aParam, PRUint8 aType, PRBool aIsOut,
|
|||
break;
|
||||
}
|
||||
|
||||
case nsXPTType::T_PSTRING_SIZE_IS:
|
||||
case nsXPTType::T_PWSTRING_SIZE_IS:
|
||||
{
|
||||
NS_PRECONDITION(!aIsArrayElement, "sized string array not supported");
|
||||
|
||||
LOG(("Sized string\n"));
|
||||
jstring data = nsnull;
|
||||
if (!aIsOut) { // 'in'
|
||||
data = (jstring) aParam;
|
||||
} else if (aParam) { // 'inout'
|
||||
data = (jstring) env->GetObjectArrayElement((jobjectArray) aParam,
|
||||
aIndex);
|
||||
}
|
||||
|
||||
PRUint32 length = 0;
|
||||
if (data) {
|
||||
if (aType == nsXPTType::T_PSTRING_SIZE_IS) {
|
||||
length = env->GetStringUTFLength(data);
|
||||
} else {
|
||||
length = env->GetStringLength(data);
|
||||
}
|
||||
if (length > aArraySize) {
|
||||
rv = NS_ERROR_ILLEGAL_VALUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
PRUint32 size_of_char = (aType == nsXPTType::T_PSTRING_SIZE_IS) ?
|
||||
sizeof(char) : sizeof(jchar);
|
||||
PRUint32 allocLength = (aArraySize + 1) * size_of_char;
|
||||
void* buf = nsMemory::Alloc(allocLength);
|
||||
if (!buf) {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
|
||||
if (data) {
|
||||
if (aType == nsXPTType::T_PSTRING_SIZE_IS) {
|
||||
const char* str = env->GetStringUTFChars(data, nsnull);
|
||||
if (!str) {
|
||||
nsMemory::Free(buf);
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
memcpy(buf, str, length);
|
||||
env->ReleaseStringUTFChars(data, str);
|
||||
} else {
|
||||
jchar* jchar_str = NS_STATIC_CAST(jchar*, buf);
|
||||
env->GetStringRegion(data, 0, length, jchar_str);
|
||||
}
|
||||
}
|
||||
|
||||
aVariant.val.p = buf;
|
||||
if (aIsOut) { // 'inout'
|
||||
aVariant.ptr = &aVariant.val;
|
||||
aVariant.SetPtrIsData();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
NS_WARNING("unexpected parameter type");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
@ -1240,7 +1301,7 @@ FinalizeParams(JNIEnv *env, const nsXPTParamInfo &aParamInfo, PRUint8 aType,
|
|||
// cleanup
|
||||
// If this is not an out param or if the invokeResult is a failure case,
|
||||
// then the array elements have not been cleaned up. Do so now.
|
||||
if (!aParamInfo.IsOut() || NS_FAILED(aInvokeResult)) {
|
||||
if (!aParamInfo.IsOut() || (NS_FAILED(aInvokeResult) && aVariant.val.p)) {
|
||||
nsXPTCVariant var;
|
||||
for (PRUint32 i = 0; i < aArraySize; i++) {
|
||||
rv = GetNativeArrayElement(aArrayType, aVariant.val.p, i, &var);
|
||||
|
@ -1254,6 +1315,48 @@ FinalizeParams(JNIEnv *env, const nsXPTParamInfo &aParamInfo, PRUint8 aType,
|
|||
break;
|
||||
}
|
||||
|
||||
case nsXPTType::T_PSTRING_SIZE_IS:
|
||||
case nsXPTType::T_PWSTRING_SIZE_IS:
|
||||
{
|
||||
NS_PRECONDITION(!aIsArrayElement, "sized string array not supported");
|
||||
|
||||
if ((aParamInfo.IsOut()) && NS_SUCCEEDED(aInvokeResult))
|
||||
{
|
||||
// create new string from data
|
||||
jstring str = nsnull;
|
||||
if (aVariant.val.p) {
|
||||
if (aType == nsXPTType::T_PSTRING_SIZE_IS) {
|
||||
PRUint32 len = (aArraySize + 1) * sizeof(char);
|
||||
char* buf = (char*) nsMemory::Alloc(len);
|
||||
if (buf) {
|
||||
memcpy(buf, aVariant.val.p, len);
|
||||
buf[aArraySize] = '\0';
|
||||
str = env->NewStringUTF((const char*) buf);
|
||||
nsMemory::Free(buf);
|
||||
}
|
||||
} else {
|
||||
str = env->NewString((const jchar*) aVariant.val.p, aArraySize);
|
||||
}
|
||||
if (!str) {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (aParamInfo.IsRetval()) {
|
||||
*aParam = str;
|
||||
} else if (*aParam) {
|
||||
// put new string into output array
|
||||
env->SetObjectArrayElement((jobjectArray) *aParam, aIndex, str);
|
||||
}
|
||||
}
|
||||
|
||||
// cleanup
|
||||
if (aVariant.val.p)
|
||||
nsMemory::Free(aVariant.val.p);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
NS_WARNING("unexpected parameter type");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
@ -1411,45 +1514,25 @@ JAVAPROXY_NATIVE(callXPCOMMethod) (JNIEnv *env, jclass that, jobject aJavaProxy,
|
|||
}
|
||||
memset(params, 0, paramCount * sizeof(nsXPTCVariant));
|
||||
|
||||
PRBool foundDependentParam = PR_FALSE;
|
||||
for (PRUint8 i = 0; i < paramCount && NS_SUCCEEDED(rv); i++)
|
||||
{
|
||||
LOG(("\t Param %d: ", i));
|
||||
const nsXPTParamInfo ¶mInfo = methodInfo->GetParam(i);
|
||||
params[i].type = paramInfo.GetType();
|
||||
|
||||
if (params[i].type.IsDependent() && paramInfo.IsIn()) {
|
||||
foundDependentParam = PR_TRUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (paramInfo.IsIn()) {
|
||||
PRUint8 type = params[i].type.TagPart();
|
||||
|
||||
// is paramater an array?
|
||||
PRUint8 arrayType = 0;
|
||||
PRUint32 arraySize = 0;
|
||||
if (type == nsXPTType::T_ARRAY) {
|
||||
// get array type
|
||||
nsXPTType xpttype;
|
||||
rv = iinfo->GetTypeForParam(methodIndex, ¶mInfo, 1, &xpttype);
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
arrayType = xpttype.TagPart();
|
||||
|
||||
// get size of array
|
||||
PRUint8 argnum;
|
||||
rv = iinfo->GetSizeIsArgNumberForParam(methodIndex, ¶mInfo, 0,
|
||||
&argnum);
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
arraySize = params[argnum].val.u32;
|
||||
}
|
||||
|
||||
// get IID for interface params
|
||||
nsID iid;
|
||||
if (type == nsXPTType::T_INTERFACE ||
|
||||
type == nsXPTType::T_INTERFACE_IS ||
|
||||
type == nsXPTType::T_ARRAY &&
|
||||
(arrayType == nsXPTType::T_INTERFACE ||
|
||||
arrayType == nsXPTType::T_INTERFACE_IS))
|
||||
{
|
||||
PRUint8 paramType = type == nsXPTType::T_ARRAY ? arrayType : type;
|
||||
rv = GetIIDForMethodParam(iinfo, methodInfo, paramInfo, paramType,
|
||||
if (type == nsXPTType::T_INTERFACE) {
|
||||
rv = GetIIDForMethodParam(iinfo, methodInfo, paramInfo, type,
|
||||
methodIndex, params, PR_TRUE, iid);
|
||||
}
|
||||
|
||||
|
@ -1458,8 +1541,8 @@ JAVAPROXY_NATIVE(callXPCOMMethod) (JNIEnv *env, jclass that, jobject aJavaProxy,
|
|||
if (aParams && !paramInfo.IsRetval()) {
|
||||
param = env->GetObjectArrayElement(aParams, i);
|
||||
}
|
||||
rv = SetupParams(env, param, type, paramInfo.IsOut(), iid, arrayType,
|
||||
arraySize, PR_FALSE, 0, params[i]);
|
||||
rv = SetupParams(env, param, type, paramInfo.IsOut(), iid, 0, 0,
|
||||
PR_FALSE, 0, params[i]);
|
||||
}
|
||||
} else {
|
||||
LOG(("out/retval\n"));
|
||||
|
@ -1467,6 +1550,76 @@ JAVAPROXY_NATIVE(callXPCOMMethod) (JNIEnv *env, jclass that, jobject aJavaProxy,
|
|||
params[i].SetPtrIsData();
|
||||
}
|
||||
}
|
||||
|
||||
// Handle any dependent params by doing a second pass
|
||||
if (foundDependentParam) {
|
||||
|
||||
for (PRUint8 j = 0; j < paramCount && NS_SUCCEEDED(rv); j++) {
|
||||
|
||||
const nsXPTParamInfo ¶mInfo = methodInfo->GetParam(j);
|
||||
params[j].type = paramInfo.GetType();
|
||||
|
||||
if (!params[j].type.IsDependent())
|
||||
continue;
|
||||
|
||||
if (paramInfo.IsIn()) {
|
||||
PRUint8 type = params[j].type.TagPart();
|
||||
|
||||
// is paramater an array or sized string?
|
||||
PRUint8 arrayType = 0;
|
||||
PRUint32 arraySize = 0;
|
||||
PRBool isArray = params[j].type.IsArray();
|
||||
PRBool isSizedString = isArray ? PR_FALSE :
|
||||
type == nsXPTType::T_PSTRING_SIZE_IS ||
|
||||
type == nsXPTType::T_PWSTRING_SIZE_IS;
|
||||
|
||||
if (isArray) {
|
||||
// get array type
|
||||
nsXPTType xpttype;
|
||||
rv = iinfo->GetTypeForParam(methodIndex, ¶mInfo, 1, &xpttype);
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
arrayType = xpttype.TagPart();
|
||||
// IDL 'octet' arrays are not 'promoted' to short, but kept as 'byte';
|
||||
// therefore, treat as a signed 8bit value
|
||||
if (arrayType == nsXPTType::T_U8)
|
||||
arrayType = nsXPTType::T_I8;
|
||||
}
|
||||
|
||||
if (isArray || isSizedString) {
|
||||
// get size of array or string
|
||||
PRUint8 argnum;
|
||||
rv = iinfo->GetSizeIsArgNumberForParam(methodIndex, ¶mInfo, 0,
|
||||
&argnum);
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
arraySize = params[argnum].val.u32;
|
||||
}
|
||||
|
||||
// get IID for interface params
|
||||
nsID iid;
|
||||
if (type == nsXPTType::T_INTERFACE_IS ||
|
||||
type == nsXPTType::T_ARRAY &&
|
||||
(arrayType == nsXPTType::T_INTERFACE ||
|
||||
arrayType == nsXPTType::T_INTERFACE_IS))
|
||||
{
|
||||
PRUint8 paramType = type == nsXPTType::T_ARRAY ? arrayType : type;
|
||||
rv = GetIIDForMethodParam(iinfo, methodInfo, paramInfo, paramType,
|
||||
methodIndex, params, PR_TRUE, iid);
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
jobject param = nsnull;
|
||||
if (aParams && !paramInfo.IsRetval()) {
|
||||
param = env->GetObjectArrayElement(aParams, j);
|
||||
}
|
||||
rv = SetupParams(env, param, type, paramInfo.IsOut(), iid, arrayType,
|
||||
arraySize, PR_FALSE, 0, params[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
ThrowException(env, rv, "SetupParams failed");
|
||||
return nsnull;
|
||||
|
@ -1493,17 +1646,28 @@ JAVAPROXY_NATIVE(callXPCOMMethod) (JNIEnv *env, jclass that, jobject aJavaProxy,
|
|||
const nsXPTParamInfo ¶mInfo = methodInfo->GetParam(i);
|
||||
PRUint8 type = paramInfo.GetType().TagPart();
|
||||
|
||||
// is paramater an array?
|
||||
// is paramater an array or sized string?
|
||||
PRUint8 arrayType = 0;
|
||||
PRUint32 arraySize = 0;
|
||||
if (type == nsXPTType::T_ARRAY) {
|
||||
PRBool isArray = params[i].type.IsArray();
|
||||
PRBool isSizedString = isArray ? PR_FALSE :
|
||||
type == nsXPTType::T_PSTRING_SIZE_IS ||
|
||||
type == nsXPTType::T_PWSTRING_SIZE_IS;
|
||||
|
||||
if (isArray) {
|
||||
// get array type
|
||||
nsXPTType array_xpttype;
|
||||
rv = iinfo->GetTypeForParam(methodIndex, ¶mInfo, 1, &array_xpttype);
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
arrayType = array_xpttype.TagPart();
|
||||
// IDL 'octet' arrays are not 'promoted' to short, but kept as 'byte';
|
||||
// therefore, treat as a signed 8bit value
|
||||
if (arrayType == nsXPTType::T_U8)
|
||||
arrayType = nsXPTType::T_I8;
|
||||
}
|
||||
|
||||
if (isArray || isSizedString) {
|
||||
// get size of array
|
||||
PRUint8 argnum;
|
||||
rv = iinfo->GetSizeIsArgNumberForParam(methodIndex, ¶mInfo, 0,
|
||||
|
@ -1536,16 +1700,12 @@ JAVAPROXY_NATIVE(callXPCOMMethod) (JNIEnv *env, jclass that, jobject aJavaProxy,
|
|||
rv = FinalizeParams(env, paramInfo, type, params[i], iid, PR_FALSE,
|
||||
arrayType, arraySize, 0, invokeResult, javaElement);
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
ThrowException(env, rv, "FinalizeParams failed");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// Normally, we would delete any created nsID object in the above loop.
|
||||
// However, GetIIDForMethodParam may need some of the nsID params when it's
|
||||
// looking for the IID of an INTERFACE_IS. Therefore, we can't delete it
|
||||
// until we've gone through the 'Finalize' loop once and created the result.
|
||||
for (PRUint8 j = 0; j < paramCount && NS_SUCCEEDED(rv); j++)
|
||||
for (PRUint8 j = 0; j < paramCount; j++)
|
||||
{
|
||||
const nsXPTParamInfo ¶mInfo = methodInfo->GetParam(j);
|
||||
const nsXPTType &type = paramInfo.GetType();
|
||||
|
@ -1567,6 +1727,10 @@ JAVAPROXY_NATIVE(callXPCOMMethod) (JNIEnv *env, jclass that, jobject aJavaProxy,
|
|||
message.AppendLiteral("\" returned an error condition");
|
||||
ThrowException(env, invokeResult, message.get());
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
ThrowException(env, rv, "FinalizeParams failed");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
LOG(("<=== (XPCOM) %s::%s()\n", ifaceName, methodInfo->GetName()));
|
||||
return result;
|
||||
|
|
|
@ -49,6 +49,7 @@ DIRS = $(DEPTH)/js/src/xpconnect/tests/idl
|
|||
|
||||
XPIDLSRCS = \
|
||||
nsIJXTestParams.idl \
|
||||
nsIJXTestArrayParams.idl \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_COMPONENTS = \
|
||||
|
|
|
@ -37,17 +37,22 @@
|
|||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.mozilla.xpcom.Mozilla;
|
||||
import org.mozilla.xpcom.XPCOMException;
|
||||
import org.mozilla.interfaces.nsIEcho;
|
||||
import org.mozilla.interfaces.nsIJXTestArrayParams;
|
||||
import org.mozilla.interfaces.nsIJXTestParams;
|
||||
import org.mozilla.interfaces.nsIStackFrame;
|
||||
import org.mozilla.interfaces.nsISupports;
|
||||
import org.mozilla.interfaces.nsITestXPCFunctionCallback;
|
||||
import org.mozilla.interfaces.nsITestXPCSomeUselessThing;
|
||||
import org.mozilla.interfaces.nsIXPCTestArray;
|
||||
import org.mozilla.interfaces.nsIXPCTestIn;
|
||||
import org.mozilla.xpcom.Mozilla;
|
||||
import org.mozilla.xpcom.XPCOMException;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -93,7 +98,10 @@ public class TestParams {
|
|||
runEchoTests();
|
||||
|
||||
runInTests();
|
||||
} catch (RunTestsException e) {
|
||||
|
||||
runArrayTests();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
|
@ -104,6 +112,7 @@ public class TestParams {
|
|||
try {
|
||||
jstest.runTests(new JavaTests());
|
||||
} catch (XPCOMException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
|
@ -169,17 +178,16 @@ public class TestParams {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param aCallee
|
||||
* @param aCallee Object on which to run tests
|
||||
* @param aTests An array of tests to run. The format looks like this:
|
||||
* index 0: method name of test to run
|
||||
* 1: Object array of method arguments
|
||||
* 2: expected result
|
||||
* 3: comment to use when logging test result; if
|
||||
* <code>null</code>, uses method name
|
||||
* @throws RunTestsException if any of the tests fails
|
||||
* @throws RuntimeException if any of the tests fails
|
||||
*/
|
||||
private static void runTestsArray(Object aCallee, Object[][] aTests)
|
||||
throws RunTestsException {
|
||||
private static void runTestsArray(Object aCallee, Object[][] aTests) {
|
||||
boolean succeeded = true;
|
||||
for (int i = 0; i < aTests.length; i++) {
|
||||
Method method = getMethod(aCallee.getClass(), (String) aTests[i][0]);
|
||||
|
@ -214,7 +222,64 @@ public class TestParams {
|
|||
}
|
||||
|
||||
if (!succeeded) {
|
||||
throw new RunTestsException();
|
||||
throw new RuntimeException("RunTestsArray did not succeed");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param aCallee Object on which to run tests
|
||||
* @param aTests An array of tests to run. The format looks like this:
|
||||
* index 0: method name of test to run
|
||||
* 1: Object array of method arguments
|
||||
* 2: comparator method that checks result
|
||||
* 3: comment to use when logging test result; if
|
||||
* <code>null</code>, uses method name
|
||||
* @throws RuntimeException if any of the tests fails
|
||||
*/
|
||||
private static void runTestsArrayWithComparator(Object aCallee,
|
||||
Object[][] aTests) {
|
||||
boolean succeeded = true;
|
||||
for (int i = 0; i < aTests.length; i++) {
|
||||
Method method = getMethod(aCallee.getClass(), (String) aTests[i][0]);
|
||||
|
||||
String comment = (aTests[i][3] != null) ? (String) aTests[i][3] :
|
||||
(String) aTests[i][0];
|
||||
|
||||
Object result = null;
|
||||
boolean passed = false;
|
||||
Exception exp = null;
|
||||
Object[] args = (Object[]) aTests[i][1];
|
||||
try {
|
||||
result = method.invoke(aCallee, args);
|
||||
} catch (Exception e) {
|
||||
exp = e;
|
||||
if (exp instanceof InvocationTargetException) {
|
||||
exp = (Exception) ((InvocationTargetException) exp).getCause();
|
||||
}
|
||||
}
|
||||
|
||||
// call comparator method to see if test passed
|
||||
try {
|
||||
IResultComparator r = (IResultComparator) aTests[i][2];
|
||||
passed = r.didPass(args, result, exp);
|
||||
} catch (Exception e) {
|
||||
exp = e;
|
||||
passed = false;
|
||||
}
|
||||
|
||||
logResult(comment, passed);
|
||||
|
||||
if (!passed) {
|
||||
succeeded = false;
|
||||
if (exp != null) {
|
||||
System.err.println("*** TEST " + comment + " threw exception:");
|
||||
exp.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!succeeded) {
|
||||
throw new RuntimeException("RunTestsArray did not succeed");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -229,10 +294,10 @@ public class TestParams {
|
|||
}
|
||||
|
||||
private static void logResult(String comment, boolean passed) {
|
||||
System.out.println(comment + "\t\t" + (passed ? "passed" : "FAILED"));
|
||||
System.out.println((passed ? "passed" : "FAILED") + ": " + comment);
|
||||
}
|
||||
|
||||
private static void runEchoTests() throws RunTestsException {
|
||||
private static void runEchoTests() {
|
||||
nsIEcho nativeEcho = (nsIEcho) Mozilla.getInstance()
|
||||
.getComponentManager()
|
||||
.createInstanceByContractID("@mozilla.org/javaxpcom/tests/xpc;1",
|
||||
|
@ -332,7 +397,7 @@ public class TestParams {
|
|||
runTestsArray(nativeEcho, tests);
|
||||
}
|
||||
|
||||
private static void runInTests() throws RunTestsException {
|
||||
private static void runInTests() {
|
||||
nsIXPCTestIn nativeInTest = (nsIXPCTestIn) Mozilla.getInstance()
|
||||
.getComponentManager()
|
||||
.createInstanceByContractID("@mozilla.org/javaxpcom/tests/xpc;1",
|
||||
|
@ -387,12 +452,10 @@ public class TestParams {
|
|||
"echoBoolean w/ " + Boolean.FALSE},
|
||||
{ "echoBoolean", new Object[] { Boolean.TRUE }, Boolean.TRUE,
|
||||
"echoBoolean w/ " + Boolean.TRUE },
|
||||
/* XXX bug 367793
|
||||
{ "echoOctet", new Object[] { zeroShort }, zeroShort,
|
||||
"echoOctet w/ zero"},
|
||||
{ "echoOctet", new Object[] { maxUByte }, maxUByte,
|
||||
"echoOctet w/ " + maxUByte },
|
||||
*/
|
||||
{ "echoLongLong", new Object[] { minLong }, minLong,
|
||||
"echoLongLong w/ " + minLong },
|
||||
{ "echoLongLong", new Object[] { maxLong }, maxLong,
|
||||
|
@ -486,10 +549,298 @@ public class TestParams {
|
|||
|
||||
runTestsArray(nativeInTest, tests);
|
||||
}
|
||||
}
|
||||
|
||||
class RunTestsException extends Exception {
|
||||
private static final long serialVersionUID = -2865653674109284035L;
|
||||
private static void runArrayTests() {
|
||||
/*** nsIXPCTestArray ***/
|
||||
|
||||
nsIXPCTestArray xpcArrayTests = (nsIXPCTestArray) Mozilla.getInstance()
|
||||
.getComponentManager()
|
||||
.createInstanceByContractID("@mozilla.org/javaxpcom/tests/xpc;1",
|
||||
null, nsIXPCTestArray.NS_IXPCTESTARRAY_IID);
|
||||
|
||||
boolean succeeded = true;
|
||||
|
||||
final int[][] intArray = { { 1, 2, 3, 4, 0, -1, -2, -3, -4 } };
|
||||
int[][] intArrayCopy = (int[][]) intArray.clone();
|
||||
Integer multiple = new Integer(2);
|
||||
|
||||
final String[][] str = { { "this", "is", "to", "be", "reversed" } };
|
||||
String[][] strCopy = (String[][]) str.clone();
|
||||
long[] count = { strCopy[0].length };
|
||||
|
||||
String[][] strCopy2 = (String[][]) str.clone();
|
||||
|
||||
Object[][] tests = new Object[][] {
|
||||
{ "multiplyEachItemInIntegerArray",
|
||||
new Object[] { multiple, new Long(intArrayCopy[0].length), intArrayCopy },
|
||||
new IResultComparator() {
|
||||
public boolean didPass(Object[] args, Object result, Exception e) {
|
||||
if (e != null)
|
||||
return false;
|
||||
int m = ((Integer) args[0]).intValue();
|
||||
int[][] resultArray = (int[][]) args[2];
|
||||
for (int i = 0; i < intArray[0].length; i++) {
|
||||
if (intArray[0][i] * m != resultArray[0][i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
},
|
||||
null
|
||||
},
|
||||
{ "doubleStringArray",
|
||||
new Object[] { count, strCopy },
|
||||
new IResultComparator() {
|
||||
public boolean didPass(Object[] args, Object result, Exception e) {
|
||||
if (e != null)
|
||||
return false;
|
||||
int inLength = str[0].length;
|
||||
int outLength = (int) ((long[]) args[0])[0];
|
||||
if (outLength != inLength * 2)
|
||||
return false;
|
||||
|
||||
String[][] resultArray = (String[][]) args[1];
|
||||
for (int i = 0; i < inLength; i++) {
|
||||
String doubled = doubleString(str[0][i]);
|
||||
if (!doubled.equals(resultArray[0][i*2]) ||
|
||||
!doubled.equals(resultArray[0][i*2+1]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private String doubleString(String string) {
|
||||
StringBuffer buf = new StringBuffer(string.length()*2);
|
||||
for (int i = 0; i < string.length(); i++) {
|
||||
buf.append(string.charAt(i));
|
||||
buf.append(string.charAt(i));
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
},
|
||||
null
|
||||
},
|
||||
{ "reverseStringArray",
|
||||
new Object[] { new Long(strCopy2[0].length), strCopy2 },
|
||||
new IResultComparator() {
|
||||
public boolean didPass(Object[] args, Object result, Exception e) {
|
||||
if (e != null)
|
||||
return false;
|
||||
int length = ((Long) args[0]).intValue();
|
||||
String[][] resultArray = (String[][]) args[1];
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (!str[0][i].equals(resultArray[0][length - 1 - i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
},
|
||||
null
|
||||
}
|
||||
};
|
||||
|
||||
runTestsArrayWithComparator(xpcArrayTests, tests);
|
||||
|
||||
|
||||
/*** nsIJXTestArrayParams ***/
|
||||
|
||||
nsIJXTestArrayParams arrayTests = (nsIJXTestArrayParams) xpcArrayTests
|
||||
.queryInterface(nsIJXTestArrayParams.NS_IJXTESTARRAYPARAMS_IID);
|
||||
|
||||
System.arraycopy(intArray[0], 0, intArrayCopy[0], 0, intArray[0].length);
|
||||
int[][] resultArray = new int[1][];
|
||||
IResultComparator copyIntArrayResultComparator = new IResultComparator() {
|
||||
public boolean didPass(Object[] args, Object result, Exception e) {
|
||||
if (e != null)
|
||||
return false;
|
||||
int inLength = ((Long) args[1]).intValue();
|
||||
int[][] resultArray = (int[][]) args[2];
|
||||
for (int i = 0; i < inLength; i++) {
|
||||
if (intArray[0][i] != resultArray[0][i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
// for tests that are expected to throw ArrayIndexOutOfBoundsException
|
||||
IResultComparator arrayIOBExpComparator = new IResultComparator() {
|
||||
public boolean didPass(Object[] args, Object result, Exception e) {
|
||||
if (e != null) {
|
||||
if (e instanceof ArrayIndexOutOfBoundsException)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
String[] returnString = new String[1];
|
||||
IResultComparator stringComparator = new IResultComparator() {
|
||||
public boolean didPass(Object[] args, Object result, Exception e) {
|
||||
if (e != null)
|
||||
return false;
|
||||
String inString = (String) args[0];
|
||||
int inLength = ((Long) args[1]).intValue();
|
||||
String[] outString = (String[]) args[2];
|
||||
if (outString[0].length() != inLength)
|
||||
return false;
|
||||
if (!inString.substring(0, inLength).equals(outString[0]))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
IResultComparator returnStringComparator = new IResultComparator() {
|
||||
public boolean didPass(Object[] args, Object result, Exception e) {
|
||||
if (e != null)
|
||||
return false;
|
||||
String inString = (String) args[0];
|
||||
int inLength = ((Long) args[1]).intValue();
|
||||
String outString = (String) result;
|
||||
if (outString.length() != inLength)
|
||||
return false;
|
||||
if (!inString.substring(0, inLength).equals(outString))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
byte[] testBytes = null;
|
||||
byte[][] returnBytes = new byte[1][];
|
||||
try {
|
||||
testBytes = utf8String.getBytes("UTF-8");
|
||||
} catch (UnsupportedEncodingException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
|
||||
tests = new Object[][] {
|
||||
{ "multiplyEachItemInIntegerArray2",
|
||||
new Object[] { multiple, intArrayCopy, new Long(intArrayCopy[0].length) },
|
||||
new IResultComparator() {
|
||||
public boolean didPass(Object[] args, Object result, Exception e) {
|
||||
if (e != null)
|
||||
return false;
|
||||
int m = ((Integer) args[0]).intValue();
|
||||
int[][] resultArray = (int[][]) args[1];
|
||||
for (int i = 0; i < intArray[0].length; i++) {
|
||||
if (intArray[0][i] * m != resultArray[0][i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
},
|
||||
null
|
||||
},
|
||||
{ "copyIntArray",
|
||||
new Object[] { intArray[0], new Long(intArray[0].length), resultArray },
|
||||
copyIntArrayResultComparator,
|
||||
null
|
||||
},
|
||||
{ "copyIntArray",
|
||||
new Object[] { intArray[0], new Long(intArray[0].length - 2), resultArray },
|
||||
copyIntArrayResultComparator,
|
||||
"copyIntArray w/ smaller count"
|
||||
},
|
||||
{ "copyIntArray",
|
||||
new Object[] { intArray[0], new Long(intArray[0].length + 2), resultArray },
|
||||
arrayIOBExpComparator,
|
||||
"copyIntArray w/ larger count"
|
||||
},
|
||||
{ "returnIntArray",
|
||||
new Object[] { intArray[0], new Long(intArray[0].length) },
|
||||
new IResultComparator() {
|
||||
public boolean didPass(Object[] args, Object result, Exception e) {
|
||||
if (e != null)
|
||||
return false;
|
||||
int[] inputArray = (int[]) args[0];
|
||||
int[] resultArray = (int[]) result;
|
||||
return Arrays.equals(resultArray, inputArray);
|
||||
}
|
||||
},
|
||||
null
|
||||
},
|
||||
{ "returnIntArray",
|
||||
new Object[] { intArray[0], new Long(intArray[0].length - 2) },
|
||||
new IResultComparator() {
|
||||
public boolean didPass(Object[] args, Object result, Exception e) {
|
||||
if (e != null)
|
||||
return false;
|
||||
int[] inputArray = (int[]) args[0];
|
||||
int inLength = ((Long) args[1]).intValue();
|
||||
int[] resultArray = (int[]) result;
|
||||
if (resultArray.length != inLength)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < inLength; i++) {
|
||||
if (resultArray[i] != inputArray[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
},
|
||||
"returnIntArray w/ smaller count"
|
||||
},
|
||||
{ "returnIntArray",
|
||||
new Object[] { intArray[0], new Long(intArray[0].length + 2) },
|
||||
arrayIOBExpComparator,
|
||||
"returnIntArray w/ larger count"
|
||||
},
|
||||
{ "copyByteArray",
|
||||
new Object[] { testBytes, new Long(testBytes.length), returnBytes },
|
||||
new IResultComparator() {
|
||||
public boolean didPass(Object[] args, Object result,
|
||||
Exception e) {
|
||||
if (e != null)
|
||||
return false;
|
||||
byte[] inArray = (byte[]) args[0];
|
||||
byte[][] outArray = (byte[][]) args[2];
|
||||
return Arrays.equals(inArray, outArray[0]);
|
||||
}
|
||||
},
|
||||
null
|
||||
},
|
||||
{ "returnByteArray",
|
||||
new Object[] { testBytes, new Long(testBytes.length) },
|
||||
new IResultComparator() {
|
||||
public boolean didPass(Object[] args, Object result,
|
||||
Exception e) {
|
||||
if (e != null)
|
||||
return false;
|
||||
byte[] inArray = (byte[]) args[0];
|
||||
byte[] outArray = (byte[]) result;
|
||||
return Arrays.equals(inArray, outArray);
|
||||
}
|
||||
},
|
||||
null
|
||||
},
|
||||
{ "copySizedString",
|
||||
new Object[] { testString, new Long(testString.length()), returnString },
|
||||
stringComparator,
|
||||
null
|
||||
},
|
||||
{ "returnSizedString",
|
||||
new Object[] { testString, new Long(testString.length()) },
|
||||
returnStringComparator,
|
||||
null
|
||||
},
|
||||
{ "copySizedWString",
|
||||
new Object[] { utf8String, new Long(utf8String.length()), returnString },
|
||||
stringComparator,
|
||||
null
|
||||
},
|
||||
{ "returnSizedWString",
|
||||
new Object[] { utf8String, new Long(utf8String.length()) },
|
||||
returnStringComparator,
|
||||
null
|
||||
},
|
||||
};
|
||||
|
||||
runTestsArrayWithComparator(arrayTests, tests);
|
||||
|
||||
if (!succeeded) {
|
||||
throw new RuntimeException("Array tests did not succeed");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class JavaTests implements nsIEcho, nsIXPCTestIn {
|
||||
|
@ -646,14 +997,14 @@ class JavaTests implements nsIEcho, nsIXPCTestIn {
|
|||
throw new XPCOMException(Mozilla.NS_ERROR_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
public void sendInOutManyTypes(byte[] p1, short[] p2, int[] p3, long[] p4,
|
||||
byte[] p5, int[] p6, long[] p7, double[] p8, float[] p9,
|
||||
public void sendInOutManyTypes(short[] p1, short[] p2, int[] p3, long[] p4,
|
||||
short[] p5, int[] p6, long[] p7, double[] p8, float[] p9,
|
||||
double[] p10, boolean[] p11, char[] p12, char[] p13, String[] p14,
|
||||
String[] p15, String[] p16) {
|
||||
throw new XPCOMException(Mozilla.NS_ERROR_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
public void sendManyTypes(byte p1, short p2, int p3, long p4, byte p5,
|
||||
public void sendManyTypes(short p1, short p2, int p3, long p4, short p5,
|
||||
int p6, long p7, double p8, float p9, double p10, boolean p11,
|
||||
char p12, char p13, String p14, String p15, String p16) {
|
||||
throw new XPCOMException(Mozilla.NS_ERROR_NOT_IMPLEMENTED);
|
||||
|
@ -721,7 +1072,7 @@ class JavaTests implements nsIEcho, nsIXPCTestIn {
|
|||
return ll;
|
||||
}
|
||||
|
||||
public byte echoOctet(byte o) {
|
||||
public short echoOctet(short o) {
|
||||
return o;
|
||||
}
|
||||
|
||||
|
@ -784,4 +1135,35 @@ class JavaTests implements nsIEcho, nsIXPCTestIn {
|
|||
return wc;
|
||||
}
|
||||
|
||||
public void copyIntArray(int[] srcArray, long count, int[][] dstArray) {
|
||||
System.arraycopy(srcArray, 0, dstArray[0], 0, (int) count);
|
||||
}
|
||||
|
||||
public void copySizedString(String srcString, long count, String[] dstString) {
|
||||
dstString[0] = srcString.substring(0, (int) count);
|
||||
}
|
||||
|
||||
public void multiplyEachItemInIntegerArray2(int val, int[][] valueArray,
|
||||
long count) {
|
||||
for(int i = 0; i < count; i++) {
|
||||
valueArray[0][i] *= val;
|
||||
}
|
||||
}
|
||||
|
||||
public int[] returnIntArray(int[] srcArray, long count) {
|
||||
int[] array = new int[(int) count];
|
||||
System.arraycopy(srcArray, 0, array, 0, (int) count);
|
||||
return array;
|
||||
}
|
||||
|
||||
public String returnSizedString(String srcString, long count) {
|
||||
return srcString.substring(0, (int) count);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
interface IResultComparator {
|
||||
|
||||
boolean didPass(Object[] args, Object result, Exception e);
|
||||
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Java XPCOM Bindings.
|
||||
*
|
||||
* The Initial Developer of the Original Code is IBM Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* IBM Corporation. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Javier Pedemonte (jhpedemonte@gmail.com)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(fb520bac-92cf-4a6b-a2f3-eb63313d7d84)]
|
||||
interface nsIJXTestArrayParams : nsISupports
|
||||
{
|
||||
void multiplyEachItemInIntegerArray2(
|
||||
in PRInt32 val,
|
||||
[array, size_is(count)] inout PRInt32 valueArray,
|
||||
in PRUint32 count);
|
||||
|
||||
void copyIntArray([array, size_is(count)] in PRInt32 srcArray,
|
||||
in PRUint32 count, [array, size_is(count)] out PRInt32 dstArray);
|
||||
|
||||
void returnIntArray([array, size_is(count)] in PRInt32 srcArray,
|
||||
in PRUint32 count,
|
||||
[retval, array, size_is(count)] out PRInt32 dstArray);
|
||||
|
||||
void copyByteArray([array, size_is(count)] in octet srcArray,
|
||||
in PRUint32 count, [array, size_is(count)] out octet dstArray);
|
||||
|
||||
void returnByteArray([array, size_is(count)] in octet srcArray,
|
||||
in PRUint32 count,
|
||||
[retval, array, size_is(count)] out octet dstArray);
|
||||
|
||||
void copySizedString([size_is(count)] in string srcString,
|
||||
in PRUint32 count, [size_is(count)] out string dstString);
|
||||
|
||||
void returnSizedString([size_is(count)] in string srcString,
|
||||
in PRUint32 count, [retval, size_is(count)] out string dstString);
|
||||
|
||||
void copySizedWString([size_is(count)] in wstring srcString,
|
||||
in PRUint32 count, [size_is(count)] out wstring dstString);
|
||||
|
||||
void returnSizedWString([size_is(count)] in wstring srcString,
|
||||
in PRUint32 count, [retval, size_is(count)] out wstring dstString);
|
||||
};
|
|
@ -35,7 +35,7 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
function logResult(testname, passed) {
|
||||
dump(testname + "\t\t" + (passed ? "passed" : "FAILED") + "\n");
|
||||
dump((passed ? "passed" : "FAILED") + ": " + testname + "\n");
|
||||
}
|
||||
|
||||
function runTestsArray(callee, tests) {
|
||||
|
@ -184,10 +184,8 @@ function runInTests(tests) {
|
|||
[ "EchoChar", charZ, charZ, "EchoChar w/ " + charZ ],
|
||||
[ "EchoBoolean", true, true, "EchoBoolean w/ " + true ],
|
||||
[ "EchoBoolean", false, false, "EchoBoolean w/ " + false ],
|
||||
/* XXX bug 367793
|
||||
[ "EchoOctet", 0, 0, "EchoOctet w/ " + 0 ],
|
||||
[ "EchoOctet", maxOctet, maxOctet, "EchoOctet w/ " + maxOctet ],
|
||||
*/
|
||||
[ "EchoLongLong", lowLong, lowLong, "EchoLongLong w/ " + lowLong ],
|
||||
[ "EchoLongLong", highLong, highLong, "EchoLongLong w/ " + highLong ],
|
||||
[ "EchoUnsignedShort", maxUShort, maxUShort,
|
||||
|
|
|
@ -41,6 +41,8 @@
|
|||
const nsISupports = Components.interfaces.nsISupports;
|
||||
const nsIEcho = Components.interfaces.nsIEcho;
|
||||
const nsIXPCTestIn = Components.interfaces.nsIXPCTestIn;
|
||||
const nsIXPCTestArray = Components.interfaces.nsIXPCTestArray;
|
||||
const nsIJXTestArrayParams = Components.interfaces.nsIJXTestArrayParams;
|
||||
|
||||
const CLASS_ID = Components.ID("{9e45a36d-7cf7-4f2a-a415-d0b07e54945b}");
|
||||
const CLASS_NAME = "XPConnect Tests in Javascript";
|
||||
|
@ -64,6 +66,8 @@ XPCTests.prototype = {
|
|||
QueryInterface: function(aIID) {
|
||||
if (!aIID.equals(nsIEcho) &&
|
||||
!aIID.equals(nsIXPCTestIn) &&
|
||||
!aIID.equals(nsIXPCTestArray) &&
|
||||
!aIID.equals(nsIJXTestArrayParams) &&
|
||||
!aIID.equals(nsISupports))
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
return this;
|
||||
|
@ -187,8 +191,80 @@ XPCTests.prototype = {
|
|||
return i;
|
||||
},
|
||||
|
||||
EchoVoid: function() {}
|
||||
EchoVoid: function() {},
|
||||
|
||||
// ----------------------------------
|
||||
// nsIXPCTestArray
|
||||
// ----------------------------------
|
||||
|
||||
MultiplyEachItemInIntegerArray : function(val, len, a) {
|
||||
for(var i = 0; i < len; i++)
|
||||
a.value[i] *= val;
|
||||
},
|
||||
|
||||
DoubleStringArray : function(len, a) {
|
||||
var outArray = new Array();
|
||||
for(var i = 0; i < len.value; i++) {
|
||||
var inStr = a.value[i];
|
||||
var outStr = new String();
|
||||
for(var k = 0; k < inStr.length; k++) {
|
||||
outStr += inStr[k];
|
||||
outStr += inStr[k];
|
||||
}
|
||||
outArray.push(outStr);
|
||||
outArray.push(outStr);
|
||||
}
|
||||
len.value *= 2;
|
||||
a.value = outArray;
|
||||
},
|
||||
|
||||
ReverseStringArray : function(len, a) {
|
||||
for(var i = 0; i < len/2; i++) {
|
||||
var temp = a.value[i];
|
||||
a.value[i] = a.value[len-1-i];
|
||||
a.value[len-1-i] = temp;
|
||||
}
|
||||
},
|
||||
|
||||
// ----------------------------------
|
||||
// nsIJXTestArrayParams
|
||||
// ----------------------------------
|
||||
|
||||
multiplyEachItemInIntegerArray2 : function(val, a, len) {
|
||||
this.MultiplyEachItemInIntegerArray(val, len, a);
|
||||
},
|
||||
|
||||
copyIntArray: function(srcArray, count, dstArray) {
|
||||
dstArray.value = srcArray.slice();
|
||||
},
|
||||
|
||||
returnIntArray: function(srcArray, count) {
|
||||
return srcArray;
|
||||
},
|
||||
|
||||
copyByteArray: function(srcArray, count, dstArray) {
|
||||
dstArray.value = srcArray.slice();
|
||||
},
|
||||
|
||||
returnByteArray: function(srcArray, count) {
|
||||
return srcArray;
|
||||
},
|
||||
|
||||
copySizedString: function(srcString, count, dstString) {
|
||||
dstString.value = srcString.slice();
|
||||
},
|
||||
|
||||
returnSizedString: function(srcString, count) {
|
||||
return srcString;
|
||||
},
|
||||
|
||||
copySizedWString: function(srcString, count, dstString) {
|
||||
dstString.value = srcString.slice();
|
||||
},
|
||||
|
||||
returnSizedWString: function(srcString, count) {
|
||||
return srcString;
|
||||
}
|
||||
};
|
||||
|
||||
/***********************************************************
|
||||
|
|
|
@ -469,14 +469,10 @@ xpcom_to_java_type(TreeState *state, IDL_tree param)
|
|||
break;
|
||||
|
||||
case IDLN_TYPE_OCTET:
|
||||
/* If real type is 'PRUint8', promote to 'short' */
|
||||
if (IDL_NODE_TYPE(state->tree) == IDLN_IDENT) {
|
||||
if (strcmp(IDL_IDENT(state->tree).str, "PRUint8") == 0) {
|
||||
fputs("short", state->file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fputs("byte", state->file);
|
||||
if (param && IDL_tree_property_get(IDL_PARAM_DCL(param).simple_declarator, "array"))
|
||||
fputs("byte", state->file);
|
||||
else
|
||||
fputs("short", state->file);
|
||||
break;
|
||||
|
||||
case IDLN_TYPE_FLOAT:
|
||||
|
|
Загрузка…
Ссылка в новой задаче