Ion C
C library for Ion
Loading...
Searching...
No Matches
ion_int.h
Go to the documentation of this file.
1/*
2 * Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License").
5 * You may not use this file except in compliance with the License.
6 * A copy of the License is located at:
7 *
8 * http://aws.amazon.com/apache2.0/
9 *
10 * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
12 * language governing permissions and limitations under the License.
13 */
16//
17// Ion int, arbitrary integer representation
18//
19// Primary use cases are deserialization and serialization
20// of arbitarty integer values in either text (decimal)
21// or binary (base 256) representation. This requires
22// the ability to convert between the two representations.
23// This also includes a limited abilty to get the values
24// out in more conventional data formats as well.
25//
26// This version X is mildly optimized for a 32 bit
27// int with 64 bit int support (i.e. 32 bit arch,
28// even though 64 bit is common)
29//
30
31#ifndef ION_INT_H_
32#define ION_INT_H_
33
34 #ifndef ION_INT_INITTO
35 #define ION_INT_INITTO /* nothing */
36 #ifdef ION_INT_INIT
37 #undef ION_INT_INIT
38 #endif
39 #else
40 #ifndef ION_INT_INIT
41 #define ION_INT_INIT init
42 #endif
43 #endif
44
45 #ifndef ION_INT_GLOBAL
46 #define ION_INT_GLOBAL extern
47 #endif
48
49#include <string.h>
50#include "ion_types.h"
51#include "ion_platform_config.h"
52#include "ion_decimal.h"
53
54#ifdef __cplusplus
55extern "C" {
56#endif
57
58// moved to ion_types.h typedef struct _ion_int ION_INT;
59
60typedef uint32_t II_DIGIT;
61typedef uint64_t II_LONG_DIGIT;
62
63#define II_PLUS '+'
64#define II_MINUS '-'
65
66#define II_BASE ((uint32_t)0x80000000)
67#define II_MASK ((uint32_t)0x7FFFFFFF)
68#define II_SHIFT ((uint32_t)31)
69
70#define II_BITS_PER_II_DIGIT II_SHIFT
71#define II_DIGIT_COUNT_FROM_BITS(bits) (((bits) == 0) ? 1 : (((((int)bits) - 1) / II_BITS_PER_II_DIGIT) + 1))
72
73#define II_STRING_BASE 10
74#define II_BITS_PER_DEC_DIGIT 3.35 /* upper bound beyond 1 gig */
75#define II_DEC_DIGIT_PER_BITS 3.32191780821918 /* lower bound */
76#define II_II_DIGITS_PER_DEC_DIGIT 0.108064516 /* or: (3.35/31) */
77#define II_DEC_DIGITS_PER_II_DIGIT 9.253731343 /* or: (1/.108064516) */
78
79#define DECIMAL_DIGIT_COUNT_FROM_BITS(bits) (((bits) == 0) ? 1 : ((SIZE)(((double)(bits) / II_DEC_DIGIT_PER_BITS) + 1)))
80
81#define II_BITS_PER_HEX_DIGIT 4
82#define II_HEX_BASE 16
83#define II_HEX_RADIX_CHARS "xX"
84#define II_BITS_PER_BINARY_DIGIT 1
85#define II_BINARY_BASE 2
86#define II_BINARY_RADIX_CHARS "bB"
87
88#define II_MAX_DIGIT (II_MASK) /* aka 2,147,483,647 decimal, 2 gig */
89#define II_BITS_PER_BYTE 8
90#define II_BYTE_BASE 256
91#define II_BYTE_MASK 0xFF
92#define II_BYTE_SIGN_BIT 0x80
93#define II_BYTE_NEG_OVERFLOW_LIMIT 0xFE
94
95#define II_INT64_BIT_THRESHOLD (sizeof(int64_t)*8-2) /* sign and 1 for good measure */
96
97#define II_SMALL_DIGIT_ARRAY_LENGTH ((256 / II_BITS_PER_II_DIGIT)+1)
98
99
100typedef struct _ion_int {
101 void *_owner;
102 int _signum; // sign, +1 or -1, or 0
103 SIZE _len; // number of digits in the _digits array (-1 if null)
104 II_DIGIT *_digits; // array of "digits" in some large base (2^31 currently)
105} _ion_int;
106
107ION_INT_GLOBAL II_DIGIT g_int_zero_bytes[]
108#ifdef ION_INT_INIT
109 = { (II_DIGIT)0 }
110#endif
111;
112ION_INT_GLOBAL ION_INT g_Int_Zero
113#ifdef ION_INT_INIT
114 = { NULL,
115 0,
116 1,
117 g_int_zero_bytes
118 }
119#endif
120;
121ION_INT_GLOBAL ION_INT g_Int_Null
122#ifdef ION_INT_INIT
123 = { NULL,
124 0,
125 0,
126 NULL
127 }
128#endif
129;
130
131ION_INT_GLOBAL THREAD_LOCAL_STORAGE BOOL g_ion_int_globals_initialized; // NOTE: this is initialized to 0 according to C standard.
132ION_INT_GLOBAL THREAD_LOCAL_STORAGE decQuad g_digit_base_quad;
133ION_INT_GLOBAL THREAD_LOCAL_STORAGE decNumber g_digit_base_number;
134
135
137// public functions
139ION_API_EXPORT iERR ion_int_alloc (void *owner, ION_INT **piint);
140ION_API_EXPORT void ion_int_free (ION_INT *iint);
141ION_API_EXPORT iERR ion_int_init (ION_INT *iint, void *owner);
142ION_API_EXPORT iERR ion_int_copy (ION_INT *dst, ION_INT *src, void *owner);
143
144ION_API_EXPORT iERR ion_int_is_null (ION_INT *iint, BOOL *p_is_null);
145ION_API_EXPORT iERR ion_int_is_zero (ION_INT *iint, BOOL *p_bool);
146ION_API_EXPORT iERR ion_int_compare (ION_INT *left, ION_INT *right, int *p_result);
147ION_API_EXPORT iERR ion_int_signum (ION_INT *iint, int32_t *p_signum);
148ION_API_EXPORT iERR ion_int_highest_bit_set (ION_INT *iint, SIZE *p_pos);
149
150ION_API_EXPORT iERR ion_int_from_string (ION_INT *iint, const iSTRING p_str);
151ION_API_EXPORT iERR ion_int_from_hex_string (ION_INT *iint, const iSTRING p_str);
152ION_API_EXPORT iERR ion_int_from_binary_string(ION_INT *iint, const iSTRING p_str);
153ION_API_EXPORT iERR ion_int_from_chars (ION_INT *iint, const char *p_chars, SIZE char_limit);
154ION_API_EXPORT iERR ion_int_from_hex_chars (ION_INT *iint, const char *p_chars, SIZE char_limit);
155ION_API_EXPORT iERR ion_int_from_binary_chars(ION_INT *iint, const char *p_chars, SIZE char_limit);
156ION_API_EXPORT iERR ion_int_from_bytes (ION_INT *iint, BYTE *buf, SIZE limit);
157ION_API_EXPORT iERR ion_int_from_abs_bytes (ION_INT *iint, BYTE *buf, SIZE limit, BOOL is_negative);
158ION_API_EXPORT iERR ion_int_from_long (ION_INT *iint, int64_t value);
159
163ION_API_EXPORT iERR ion_int_from_decimal (ION_INT *iint, const decQuad *p_value, decContext *context);
164
165ION_API_EXPORT iERR ion_int_char_length (ION_INT *iint, SIZE *p_len);
166ION_API_EXPORT iERR ion_int_to_char (ION_INT *iint, BYTE *p_str, SIZE len, SIZE *p_written);
167ION_API_EXPORT iERR ion_int_to_string (ION_INT *iint, hOWNER owner, iSTRING p_str);
168
169ION_API_EXPORT iERR ion_int_byte_length (ION_INT *iint, SIZE *p_byte_length);
170ION_API_EXPORT iERR ion_int_to_bytes (ION_INT *iint, SIZE starting_int_byte_offset, BYTE *buffer, SIZE buffer_length, SIZE *bytes_written);
171ION_API_EXPORT iERR ion_int_abs_bytes_length(ION_INT *iint, SIZE *p_byte_length);
172ION_API_EXPORT iERR ion_int_to_abs_bytes (ION_INT *iint, SIZE starting_int_byte_offset, BYTE *buffer, SIZE buffer_length, SIZE *bytes_written);
173ION_API_EXPORT iERR ion_int_to_int64 (ION_INT *iint, int64_t *p_int64);
174ION_API_EXPORT iERR ion_int_to_int32 (ION_INT *iint, int32_t *p_int32);
175
179ION_API_EXPORT iERR ion_int_to_decimal (ION_INT *iint, decQuad *p_quad, decContext *context);
180
182// internal functions
184void _ion_int_dump_quad(decQuad *quad, int64_t expected);
185int _ion_int_init_globals(void);
186
187iERR _ion_int_from_decimal_number(ION_INT *iint, const decNumber *p_value, decContext *context);
188iERR _ion_int_to_decimal_number(ION_INT *iint, decNumber *p_value, decContext *context);
189
190iERR _ion_int_validate_arg(const ION_INT *iint);
191iERR _ion_int_validate_arg_with_ptr(const ION_INT *iint, const void *ptr);
192iERR _ion_int_validate_non_null_arg_with_ptr(const ION_INT *iint, const void *ptr);
193
194void _ion_int_init(ION_INT *iint, void *owner);
195iERR _ion_int_zero(ION_INT *iint);
196void * _ion_int_realloc_helper(void *value, SIZE old_len, void *owner, SIZE new_len);
197iERR _ion_int_extend_digits(ION_INT *iint, SIZE digits_needed, BOOL zero_fill);
198II_DIGIT *_ion_int_buffer_temp_copy( II_DIGIT *orig_digits, SIZE len, II_DIGIT *cache_buffer, SIZE cache_len);
199II_DIGIT *_ion_int_buffer_temp_copy( II_DIGIT *orig_digits, SIZE len, II_DIGIT *cache_buffer, SIZE cache_len);
200void _ion_int_free_temp(II_DIGIT *temp_buffer, II_DIGIT *cache_buffer);
201
202BOOL _ion_int_from_bytes_helper(ION_INT *iint, BYTE *buf, SIZE byte_idx, SIZE limit, BOOL invert, BOOL includes_sign_byte);
203iERR _ion_int_from_chars_helper(ION_INT *iint, const char *str, SIZE len);
204iERR _ion_int_from_radix_chars_helper(ION_INT *iint, const char *str, SIZE len, unsigned int *digit_values, unsigned int base, unsigned int bits_per_digit, const char *radix_chars);
205iERR _ion_int_from_hex_chars_helper(ION_INT *iint, const char *str, SIZE len);
206iERR _ion_int_from_binary_chars_helper(ION_INT *iint, const char *str, SIZE len);
207
208BOOL _ion_int_is_null_helper(const ION_INT *iint);
209BOOL _ion_int_is_zero(const ION_INT *iint);
210BOOL _ion_int_is_zero_bytes(const II_DIGIT *digits, SIZE len);
211
212SIZE _ion_int_highest_bit_set_helper(const ION_INT *iint);
213
214SIZE _ion_int_get_char_len_helper(const ION_INT *iint);
215iERR _ion_int_to_string_helper(ION_INT *iint, char *strbuf, SIZE buflen, SIZE *p_written);
216
217BOOL _ion_int_is_high_bytes_high_bit_set_helper(const ION_INT *iint, SIZE abs_byte_count);
218SIZE _ion_int_bytes_length_helper(const ION_INT *iint);
219iERR _ion_int_to_bytes_helper(ION_INT *iint, SIZE bytes_in_int, SIZE starting_int_byte_offset, BOOL is_neg, BYTE *buffer, SIZE buffer_length, SIZE *bytes_written);
220
221SIZE _ion_int_abs_bytes_length_helper(const ION_INT *iint);
222SIZE _ion_int_abs_bytes_signed_length_helper(const ION_INT *iint);
223//iERR _ion_int_to_abs_bytes_helper(ION_INT *iint, SIZE bytes_in_int, SIZE starting_int_byte_offset, BOOL is_neg, BYTE *buffer, SIZE buffer_length, SIZE *bytes_written);
224
225iERR _ion_int_to_int64_helper(ION_INT *iint, int64_t *p_int64);
226
227iERR _ion_int_add_digit(II_DIGIT *digits, SIZE digit_count, II_DIGIT value);
228iERR _ion_int_sub_digit(II_DIGIT *digits, SIZE digit_count, II_DIGIT value);
229/* not used
230iERR _ion_int_multiply_by_digit(II_DIGIT *digits, SIZE digit_count, II_DIGIT value);
231*/
232iERR _ion_int_multiply_and_add(II_DIGIT *digits, SIZE digit_count, II_DIGIT mult_value, II_DIGIT add_value);
233iERR _ion_int_divide_by_digit(II_DIGIT *digits, SIZE digit_count, II_DIGIT value, II_DIGIT *p_remainder);
234
235#ifdef __cplusplus
236}
237#endif
238
239#endif /* ION_INT_H_ */
ION_API_EXPORT iERR ion_int_from_decimal(ION_INT *iint, const decQuad *p_value, decContext *context)
ION_API_EXPORT iERR ion_int_to_decimal(ION_INT *iint, decQuad *p_quad, decContext *context)
Definition ion_int.h:100
Definition ion_string.h:40