php long int to java long failed when php call java via hessian - hessian

I am using hessian between php and java service.
In php client:
$proxy = new HessianClient($testurl, $options);
$result = $proxy->waoo(309000100340);
In java server:
public Long waoo(long id) {
System.out.println(id);
return id;
}
But java printed -237544972 and php got int(4057422324).
That means java regard the input as int while it's long.
How can I solve this problem?

Perhaps there is no solution for this problem. Java received hessian binary data and deserialize it based on the data's characters. Thus the int from php will be deserialized as java int. Then java transform value to the declared type(long), but in the pervious step the int variable has been already overflown.
The alternative solution is to use string to transfer data between different language.

class HessianWriter extends HessianProtocolHandler
{
function writeObject(&$value)
{
$type = gettype($value);
switch ($type) {
case 'integer':
if (defined('HESSAIN_USE_LONG') && HESSAIN_USE_LONG)
$dispatch = 'writeLong';
else
$dispatch = 'writeInt';
break;
}
}
Set the constant HESSAIN_USE_LONG to true before calling the method and be happy

Related

Null Assertions in null-safe mode and How to Avoid If Possible

Learning Dart and using dart_code_metrics to ensure that I write code that meets expectations. One of the rules that is active is avoid-non-null-assertion.
Note, the code below was created to recreate the problem encountered in a larger code base where the value of unitString is taken from a JSON file. As such the program cannot control what is specified in the JSON file.
From pubspec.yaml
environment:
sdk: '>=2.15.0 <3.0.0'
// ignore_for_file: avoid_print
import 'package:qty/qty.dart';
void main() {
const String unitString = 'in';
// unit.Width returns null if unitString is not a unit of Length.
if (Length().unitWith(symbol: unitString) == null) {
print('units $unitString not supported.');
} else {
// The following line triggers avoid-non-null-assertion with the use of !.
final Unit<Length> units = Length().unitWith(symbol: unitString)!;
final qty = Quantity(amount: 0.0, unit: units);
print('Qty = $qty');
}
}
If I don't use ! then I get the following type error:
A value of type 'Unit<Length>?' can't be assigned to a variable of type 'Unit<Length>'.
Try changing the type of the variable, or casting the right-hand type to 'Unit<Length>'.
Casting the right-hand side to
Unit<Length>
fixes the above error but cause a new error when instantiating Quantity() since the constructor expects
Unit<Length>
and not
Unit<Length>?
I assume there is an solution but I'm new to Dart and cannot formulate the correct search query to find the answer.
How can I modify the sample code to make Dart and dart_code_metrics happy?
Your idea of checking for null before using a value is good, it's just not implemented correctly. Dart does automatically promote nullable types to non-null ones when you check for null with an if, but in this case you need to use a temporary variable.
void main() {
const String unitString = 'in';
//Use a temp variable, you could specify the type instead of using just using final
final temp = Length().unitWith(symbol: unitString);
if (temp == null) {
print('units $unitString not supported.');
} else {
final Unit<Length> units = temp;
final qty = Quantity(amount: 0.0, unit: units);
print('Qty = $qty');
}
}
The basic reason for that when you call your unitWith function and see that it's not null the first time, there's no guarantee that the when you call it again that it will still return a non-null value. I think there's another SO question that details this better, but I can't seem to find.

How to represent a C char array in Java with GraalVm

I'm consuming a C library in Java with GraalVm and I have this field (if_name) I don't know how to implement:
# define IFNAMSIZ 16
struct port_t
{
char if_name[IFNAMSIZ];
}
This is my current code:
#CStruct("port_t")
interface Port extends PointerBase {
#CField("if_name")
WordPointer getIfName();
#CField("if_name")
void setIfName(WordPointer ifName);
}
Using WordPointer I get the following error compiling:
Error: Type WordPointer has a size of 8 bytes, but accessed C value has a size of 16 bytes; to suppress this error, use the annotation #AllowNarrowingCast
I already tried with CCharPointer and CCharPointerPointer but those have fixed lengths to 8 bytes and I got a similar error when compiling.
Anyone can help?
Thanks in advance
As you already guessed, you'll need to get the address of this field to manipulate it.
You can use
#CStruct("port_t")
interface Port extends PointerBase {
#CFieldAddress("if_name")
CCharPointer addressOfIfName();
}
In this case it doesn't make sense to have a setter since you cannot change the address of this field. Instead you can use the read/write methods of CCharPointer.
You'll probably need
#CConstant
static native int IFNAMSIZ();
somewhere as well.
Then you can do things like
String foo(Port p, String newIfName) {
UnsignedWord size = WordFactory.unsigned(IFNAMSIZ());
String oldIfName = CTypeConversion.toJavaString(p.addressOfIfName(), size);
CTypeConversion.toCString(newIfName, p.addressOfIfName(), size);
return oldIfName;
}

The 'arguments' object cannot be referenced in an arrow function in ES3 and ES5. Consider using a standard function expression

Currently building a sample whiteboard project and faced a typescript issue
var format = (formatString, ...params: any[]): string => {
var i = 0;
while (/%s/.test(formatString)) {
formatString = formatString.replace('%s', arguments[++i]) --> Error at (arguments)
}
return formatString;
};
I checked the similar issue over stack overflow but didn't get a concrete answer
You are confusing the availability of rest parameters feature in JS an in typescript.
The fact that arguments object is used for functions with variable number of parameters in ES3 & ES5 should not make you use it in typescript.
For functions with variable number of parameters in typescript, you should use rest parameters. Typescript compiler will compile it to:
Js rest parameters with ES2015 target
arguments object with ES3 or ES5 target
var format = (formatString: string, ...params: any[]): string => {
var i = 0;
while (/%s/.test(formatString)) {
formatString = formatString.replace('%s', params[i++]);
}
return formatString;
};
Playground Link

Context dependent ANTLR4 ParseTreeVisitor implementation

I am working on a project where we migrate massive number (more than 12000) views to Hadoop/Impala from Oracle. I have written a small Java utility to extract view DDL from Oracle and would like to use ANTLR4 to traverse the AST and generate an Impala-compatible view DDL statement.
The most of the work is relatively simple, only involves re-writing some Oracle specific syntax quirks to Impala style. However, I am facing an issue, where I am not sure I have the best answer yet: we have a number of special cases, where values from a date field are extracted in multiple nested function calls. For example, the following extracts the day from a Date field:
TO_NUMBER(TO_CHAR(d.R_DATE , 'DD' ))
I have an ANTLR4 grammar declared for Oracle SQL and hence get the visitor callback when it reaches TO_NUMBER and TO_CHAR as well, but I would like to have special handling for this special case.
Is not there any other way than implementing the handler method for the outer function and then resorting to manual traversal of the nested structure to see
I have something like in the generated Visitor class:
#Override
public String visitNumber_function(PlSqlParser.Number_functionContext ctx) {
// FIXME: seems to be dodgy code, can it be improved?
String functionName = ctx.name.getText();
if (functionName.equalsIgnoreCase("TO_NUMBER")) {
final int childCount = ctx.getChildCount();
if (childCount == 4) {
final int functionNameIndex = 0;
final int openRoundBracketIndex = 1;
final int encapsulatedValueIndex = 2;
final int closeRoundBracketIndex = 3;
ParseTree encapsulated = ctx.getChild(encapsulatedValueIndex);
if (encapsulated instanceof TerminalNode) {
throw new IllegalStateException("TerminalNode is found at: " + encapsulatedValueIndex);
}
String customDateConversionOrNullOnOtherType =
customDateConversionFromToNumberAndNestedToChar(encapsulated);
if (customDateConversionOrNullOnOtherType != null) {
// the child node contained our expected child element, so return the converted value
return customDateConversionOrNullOnOtherType;
}
// otherwise the child was something unexpected, signalled by null
// so simply fall-back to the default handler
}
}
// some other numeric function, default handling
return super.visitNumber_function(ctx);
}
private String customDateConversionFromToNumberAndNestedToChar(ParseTree parseTree) {
// ...
}
For anyone hitting the same issue, the way to go seems to be:
changing the grammar definition and introducing custom sub-types for
the encapsulated expression of the nested function.
Then, I it is possible to hook into the processing at precisely the desired location of the Parse tree.
Using a second custom ParseTreeVisitor that captures the values of function call and delegates back the processing of the rest of the sub-tree to the main, "outer" ParseTreeVisitor.
Once the second custom ParseTreeVisitor has finished visiting all the sub-ParseTrees I had the context information I required and all the sub-tree visited properly.

Get pointer to a struct from a Dart_NativeArguments struct in C

I'm trying to wrap a C library using Dart. I call into a C function from dart and pass in the arguments through a Dart_NativeArguments struct in C:
void _sayHello(Dart_NativeArguments arguments) {
string from;
Dart_Handle seed_object = HandleError(Dart_GetNativeArgument(arguments, 0));
if (Dart_IsString(seed_object)) {
const char* seed;
HandleError(Dart_StringToCString(seed_object, &seed));
from = seed;
}
num = (int)Dart_GetNativeArgument(arguments, 1);
Dart_SetReturnValue(arguments, HandleError(Dart_NewStringFromCString(sayHello(from, num).c_str())));
}
In Dart, I call the function and pass in the necessary arguments
String sayHello(String from) native "sayHello";
main() {
print(sayHello("Dart"));
}
I was wondering how I could pass in pointers (to a struct I made) instead of just strings and ints as arguments. There are functions in Dart to convert Dart_Handles into Strings and ints but not pointers. What is the internal structure of the Dart_Handle and how would I go about converting it back to a pointer? For example:
Dart code:
String sayHello(info from) native "sayHello";
class info
{
String message;
int num;
}
main() {
info tester = new info();
tester.message = "Dart";
tester.num = 2;
print(sayHello(tester));
}
C Code:
void sayHello(Dart_NativeArguments arguments) {
/*What do I do here to get back a pointe to the struct/class I passed
in as an argument in Dart?*/
}
Your Dart_NativeArguments will consist of just one item, which will be an instance - the instance of the class info that you created with new info(). You can test whether it's an instance with bool Dart_IsInstance(Dart_Handle object). So what you have is an handle to an instance of info. This allows you to access its instance fields (message and num) to get and set them, using Dart_GetField and Dart_SetField.
Dart_Handle instance = Dart_GetNativeArgument(arguments, 0);
Dart_Handle message_handle = Dart_GetField(retobj, NewString("message"));
char* message;
Dart_StringToCString(message_handle, &message);
Dart_Handle number_handle = Dart_GetField(retobj, NewString("num"));
int64_t number;
Dart_IntegerToInt64(number_handle, &number);
// message contains the string, number contains the number
// use them, copy them etc
I know this is just an example, but it might be easier to redefine sayHello to take 2 arguments (a string and an int) rather than passing an object instance. There isn't a way to access the fields of a class in one step, you need to access them individually. Consider these two versions of the Dart code, one passing an object instance and one just the values. The second version is simpler at the Dart and C side (no GetField steps). The first version is more powerful, though, because you could update the fields using SetField, which you couldn't in the second.
class Info {
String message;
int num;
Info(this.message, this.num);
}
version1() {
sayHelloV1(new Info('Dart', 2));
}
version2() {
sayHelloV2('Dart', 2);
}
If your C API requires you to pass in a struct you will have to create that in your C code by copying the values you extract using Dart_IntegerToInt64etc into it, then pass the pointer to your C struct to the API.
If your API is very precise about the packing/padding of the data into the struct, you could use Dart typed_data to pack the Dart types into a ByteData and pass the underlying byte array.

Resources