Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with big UInt64 values #389

Closed
jozseffa opened this issue Dec 20, 2016 · 5 comments
Closed

Problem with big UInt64 values #389

jozseffa opened this issue Dec 20, 2016 · 5 comments

Comments

@jozseffa
Copy link

Using big UInt64 values like UInt64.MaxValue can not be converter to/from bson Int64, an overflow exception occurs.
Possible solution is on serialization:

    var bytes = BitConverter.GetBytes((UInt64)obj);
    var vint64 = BitConverter.ToInt64(bytes, 0);
    return newBsonValue(vint64);

deserialization:

    Int64 vint64 = (Int64)Convert.ChangeType(value.RawValue, typeof(Int64));
    var bytes = BitConverter.GetBytes(vint64);
    var vuint64 = BitConverter.ToUInt64(bytes, 0);
    return vuint64;

@mbdavid
Copy link
Collaborator

mbdavid commented Dec 20, 2016

BSON doesn't support UInt64, only Int64. It's not possible change this serialization without affect current datafiles.

It's same problem in MongoDB. Take a look here:

http://stackoverflow.com/questions/13994498/how-to-store-unsigned-long-long-uint64-t-values-in-a-mongodb-document

@jozseffa
Copy link
Author

Sorry, I mean the BsonMapper.Serialize and BsonMapper.Deserialize, convert to/from .net type UInt64.
My quick fix:

		else if (obj is UInt32)
		{
			return new BsonValue(Convert.ToInt64(obj));
		}
		else if (obj is UInt64)
		{
			var bytes = BitConverter.GetBytes((UInt64)obj);
			var vint64 = BitConverter.ToInt64(bytes, 0);
			return new BsonValue(vint64);
		}
            // simple ConvertTo to basic .NET types
            else if (_basicTypes.Contains(type))
            {
			if (type == typeof(UInt64))
			{
				Int64 vint64 = (Int64)Convert.ChangeType(value.RawValue, typeof(Int64));
				var bytes = BitConverter.GetBytes(vint64);
				var vuint64 = BitConverter.ToUInt64(bytes, 0);
				return vuint64;
			}
			return Convert.ChangeType(value.RawValue, type);
            }

@henon
Copy link

henon commented Dec 21, 2016

No need to use BitConverter. Actually to convert between Int64 and UInt64 you can just cast within unchecked( ) like this:

unchecked((UInt64)((Int64)value.RawValue))

This will cast -1 to UInt64.MaxValue without throwing IntegerOverflowException.

@mbdavid
Copy link
Collaborator

mbdavid commented Dec 21, 2016

@henon
Copy link

henon commented Dec 22, 2016

I guess so. You could do UInt32 and UInt64 conversion before that line.

Actually, instead of converting to and from BSON supported types I'd vote for extending BSON and save all basic .Net types without any conversion allowing queries with UInt64 that are not saved as potentially negative Int64, but that is another story for another thread.

mbdavid added a commit that referenced this issue Dec 25, 2016
@mbdavid mbdavid closed this as completed Jan 10, 2017
github-actions bot pushed a commit to Reddevildragg-UPM-Forks/LiteDB that referenced this issue Nov 18, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants