Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Copyright (C) 2013-2014 Sappenin Inc. (developers@sappenin.com) Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
 
 package com.sappenin.objectify.translate.util;
 
Encodes numbers as strings in such a way that the lexicographic order of the encoded strings is the same as the natural order of the original numbers. The length of an encoded number is only slightly larger than the length of its original number. Unlike other schemes, there is no limit to the size of numbers which may be encoded.

Author(s):
ted stockwell
David Fuelling
 
 public class BigDecimalCodec
 {

Parameters:
input
Returns:
 
 	public static final String decode(String input)
 	{
 
 		try
 		{
 			if (input == null)
 			{
 				return null;
 			}
 			if (input.length() <= 0)
 			{
 				return "";
 			}
 			return new Decoder(input).;
 		}
 		catch (ParseException e)
 		{
 			throw new RuntimeException("Failed to decode number:" + inpute);
 		}
 	}

Parameters:
input
Returns:
 
 	public static final BigDecimal decodeAsBigDecimal(String input)
 	{
 
 		try
 		{
 			if (input == null)
 			{
 				return null;
 			}
 			if (input.length() <= 0)
 			{
 				throw new RuntimeException("Internal Error: Cannot decode an empty String");
 			}
 			return new BigDecimal(new Decoder(input).);
 		}
 		catch (ParseException e)
 		{
 			throw new RuntimeException("Failed to decode number:" + inpute);
 		}
 	}

Parameters:
input
Returns:
 
 	public static final String encode(String input)
 	{
 
 		try
 		{
 			if (input == null)
 			{
 				return null;
 			}
 			if (input.length() <= 0)
 			{
				return "";
			}
			return new Encoder(input).;
		}
		catch (ParseException e)
		{
			throw new RuntimeException("Failed to parse number:" + inpute);
		}
	}

Parameters:
decimal
Returns:
	public static final String encode(BigDecimal decimal)
	{
		if (decimal == null)
		{
			return null;
		}
		return BigDecimalCodec.encode(decimal.toPlainString());
	}

	static public class Encoder
	{
		private String _input;
		private int _position = 0;
		private int _end;
		private String _output = "";
		private boolean _isNegative = false;
		private Encoder(String inputthrows ParseException
		{
			this. = input;
			this. = this..length();
			char c = this..charAt(this.);
			if (c == '-')
			{
				this..charAt(this.++);
				this. = true;
			}
			if (this.readDecimalPoint())
			{
				this.readNumber(this. - this.);
			}
			this. += this. ? '?' : '*';
		}

Returns:
		private boolean readDecimalPoint() throws ParseException
		{
			if (this. <= this.)
			{
				return false;
			}
			char c = this..charAt(this.++);
			if (c != '.')
			{
				this.throwParseException("Expected decimal point");
			}
			if (this. <= this.)
			{
				return false;
			}
			this. += this. ? ':' : '.';
			return true;
		}

		private void readNumberBeforeDecimal() throws ParseException
		{
			char[] buffer = new char[this..length()];
			// read number until decimal point reached or end
			int i = 0;
			while (this. > this.)
			{
				char c = this..charAt(this.++);
				if (('0' <= c) && (c <= '9'))
				{
					buffer[i++] = (char) (this. ? '0' + ('9' - c) : c);
				}
				else if (c == '.')
				{
					this.--;
					break;
				}
			}
			// now figure out needed prefixes
			String prefix = "";
			int l = i;
			String unaryPrefix = this. ? "*" : "?";
			while (1 < l)
			{
				unaryPrefix += this. ? '*' : '?';
				String s = Integer.toString(l);
				if (this.)
				{
					char[] cs = s.toCharArray();
					for (int j = 0; j < cs.lengthj++)
					{
						cs[j] = (char) (('0' + '9') - cs[j]);
					}
					s = new String(cs);
				}
				prefix = s + prefix;
				l = s.length();
			}
			this. += unaryPrefix// output unary prefix count
			this. += prefix// output prefixes
			this. += new String(buffer, 0, i); // now output actual
			// number
		}

Parameters:
length
		private void readNumber(int length)
		{
			if (this.)
			{
				while (0 < length--)
				{
					this. += (char) ('0' + ('9' - this..charAt(this.++)));
				}
			}
			else
			{
				this. += this..substring(this.this. + length);
				this. += length;
			}
		}

Parameters:
message
		private void throwParseException(String messagethrows ParseException
		{
			throw new ParseException(messagethis.);
		}
	}

	static public class Decoder
	{
		private String _input;
		private int _position = 0;
		private int _end;
		private String _output = "";
		private boolean _isNegative = false;

Parameters:
input
		private Decoder(String inputthrows ParseException
		{
			this. = input;
			this. = this..length();
			int lastChar = this..charAt(this. - 1);
			while ((lastChar == '*') || (lastChar == '?') || (lastChar == ':') || (lastChar == '.'))
			{
				lastChar = this..charAt((--this.) - 1);
			}
			char c = this..charAt(this.);
			if (c == '*')
			{
				this. += '-';
				this. = true;
			}
			else if (c != '?')
			{
				throw new ParseException("All encoded numbers must begin with either '?' or '*'"this.);
			}
			if (this.readDecimalPoint())
			{
				this.readNumber(this. - this.);
			}
		}

Returns:
		private boolean readDecimalPoint() throws ParseException
		{
			if (this. <= this.)
			{
				return false;
			}
			char c = this..charAt(this.++);
			if (c != (this. ? ':' : '.'))
			{
				throw new ParseException("Expected decimal point"this.);
			}
			if (this. <= this.)
			{
				return false;
			}
			this. += '.';
			return true;
		}

		private void readSequence() throws ParseException
		{
			int sequenceCount = 0;
			while (true)
			{
				int c = this..charAt(this.++);
				if ((c == '*') || (c == '?'))
				{
					sequenceCount++;
				}
				else
				{
					this.--;
					break;
				}
			}
			this.readNumberSequence(sequenceCount);
		}

Parameters:
sequenceCount
		private void readNumberSequence(int sequenceCount)
		{
			int prefixLength = 1;
			while (1 < sequenceCount--)
			{
				prefixLength = this.readPrefix(prefixLength);
			}
			this.readNumber(prefixLength);
		}

Parameters:
length
Returns:
		private int readPrefix(int length)
		{
			if (this.)
			{
				char[] cs = new char[length];
				int i = 0;
				while (0 < length--)
				{
					cs[i++] = (char) ('0' + ('9' - this..charAt(this.++)));
				}
				s = new String(cs);
			}
			else
			{
				s = this..substring(this.this. + length);
				this. += length;
			}
			return Integer.parseInt(s);
		}

Parameters:
length
		private void readNumber(int length)
		{
			if (this.)
			{
				while (0 < length--)
				{
					this. += (char) ('0' + ('9' - this..charAt(this.++)));
				}
			}
			else
			{
				this. += this..substring(this.this. + length);
				this. += length;
			}
		}
	}
New to GrepCode? Check out our FAQ X