Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Forced floats into doubles #63

Closed
wants to merge 3 commits into from

3 participants

Patrick Lodder Park Jung Up Brandon Alexander
Patrick Lodder
Collaborator

I ran into problems talking to a java rpc server when expecting double's but JS 'number' primitive is serialized as an int.

Scenario 1, correct serialization:

require('./lib/serializer').serializeMethodCall('foo', [parseFloat("0.5")]);
<?xml version="1.0"?>
<methodCall>
  <methodName>foo</methodName>
  <params>
    <param><value><double>0.5</double></value></param>
  </params>
</methodCall>

Scenario 2, wrong serialization:

require('./lib/serializer').serializeMethodCall('foo', [parseFloat("0.5") + parseFloat("0.5")]);
<?xml version="1.0"?>
<methodCall>
  <methodName>foo</methodName>
  <params>
    <param><value><int>1</int></value></param>
  </params>
</methodCall>

The neatest thing I could come up with is a Float class that forces number parsing as a double, but it's 5:40am so maybe there's a better solution.

require('./lib/serializer').serializeMethodCall('foo', [new xmlrpc.Float(parseFloat("0.5") + parseFloat("0.5"))]);
<?xml version="1.0"?>
<methodCall>
  <methodName>foo</methodName>
  <params>
    <param><value><double>1</double></value></param>
  </params>
</methodCall>
Park Jung Up

< Casting from int to long type >

I've not been invoked xmlrpc method, and because argument type is miss-matched.

Current : int type

callMethod('test', [10]);

Improvement : forced casting to long type

callMethod('test', [new xmlrpc.Long(10)]);
Patrick Lodder
Collaborator

It was of course only a matter of time before someone needed another type to be casted and that moment is now. I will make some time inside a commercial project to fix this matter properly and come up with a new PR because this one is not fit to merge.

I suppose the best solution would be to allow for custom types to be added to the serializer, but to not code those types inside the library like I did for float. Basically we'd need to expose 2 new functions serializer.addCustomType(constr) and serializer.removeCustomType(constr) where constr would be expected to have a toString() method and check value instanceof constr inside object serialization?

@baalexander : would that be an acceptable PR?

Brandon Alexander
Owner

@patricklodder - First, apologies for the ridiculously long time of replying. I agree some sort of way to enforce a type would be nice. Maybe a class like "CustomType" which you could extend. Then we could check

if (value instanceof "CustomType") {
  // Add value to XML (toString() or something similar)
}

Thoughts?

Patrick Lodder
Collaborator

@baalexander - I have opened a new pull request ( #75 ) for the solution as you proposed. Closing this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 23, 2012
  1. Patrick Lodder

    add float class

    patricklodder authored
  2. Patrick Lodder
  3. Patrick Lodder
This page is out of date. Refresh to see the latest.
Showing with 14 additions and 1 deletion.
  1. +3 −0  lib/float.js
  2. +10 −1 lib/serializer.js
  3. +1 −0  lib/xmlrpc.js
3  lib/float.js
View
@@ -0,0 +1,3 @@
+var Float = module.exports = function (data) {
+ if (data !== undefined) this.value = (typeof(data) == 'number') ? data : parseFloat(data);
+};
11 lib/serializer.js
View
@@ -1,5 +1,6 @@
var xmlBuilder = require('xmlbuilder')
, dateFormatter = require('./date_formatter')
+ , Float = require('./float');
/**
* Creates the XML for an XML-RPC method call.
@@ -105,6 +106,10 @@ function serializeValue(value, xml) {
appendDatetime(current.value, valueNode)
stack.pop()
}
+ else if (current.value instanceof Float) {
+ appendNumber(current.value, valueNode);
+ stack.pop();
+ }
else if (Buffer.isBuffer(current.value)) {
appendBuffer(current.value, valueNode)
stack.pop()
@@ -177,7 +182,11 @@ function appendString(value, xml) {
}
function appendNumber(value, xml) {
- if (value % 1 == 0) {
+
+ if (value instanceof Float) {
+ xml.ele('double').txt(value.value);
+ }
+ else if (value % 1 == 0) {
xml.ele('int').txt(value)
}
else {
1  lib/xmlrpc.js
View
@@ -59,3 +59,4 @@ xmlrpc.createSecureServer = function(options, callback) {
return new Server(options, true, callback)
}
+xmlrpc.Float = require('./float');
Something went wrong with that request. Please try again.