Ion C
C library for Ion
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
55 extern "C" {
56 #endif
57 
58 // moved to ion_types.h typedef struct _ion_int ION_INT;
59 
60 typedef uint32_t II_DIGIT;
61 typedef 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 
100 typedef 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 
107 ION_INT_GLOBAL II_DIGIT g_int_zero_bytes[]
108 #ifdef ION_INT_INIT
109  = { (II_DIGIT)0 }
110 #endif
111 ;
112 ION_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 ;
121 ION_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 
131 ION_INT_GLOBAL THREAD_LOCAL_STORAGE BOOL g_ion_int_globals_initialized; // NOTE: this is initialized to 0 according to C standard.
132 ION_INT_GLOBAL THREAD_LOCAL_STORAGE decQuad g_digit_base_quad;
133 ION_INT_GLOBAL THREAD_LOCAL_STORAGE decNumber g_digit_base_number;
134 
135 
137 // public functions
139 ION_API_EXPORT iERR ion_int_alloc (void *owner, ION_INT **piint);
140 ION_API_EXPORT void ion_int_free (ION_INT *iint);
141 ION_API_EXPORT iERR ion_int_init (ION_INT *iint, void *owner);
142 ION_API_EXPORT iERR ion_int_copy (ION_INT *dst, ION_INT *src, void *owner);
143 
144 ION_API_EXPORT iERR ion_int_is_null (ION_INT *iint, BOOL *p_is_null);
145 ION_API_EXPORT iERR ion_int_is_zero (ION_INT *iint, BOOL *p_bool);
146 ION_API_EXPORT iERR ion_int_compare (ION_INT *left, ION_INT *right, int *p_result);
147 ION_API_EXPORT iERR ion_int_signum (ION_INT *iint, int32_t *p_signum);
148 ION_API_EXPORT iERR ion_int_highest_bit_set (ION_INT *iint, SIZE *p_pos);
149 
150 ION_API_EXPORT iERR ion_int_from_string (ION_INT *iint, const iSTRING p_str);
151 ION_API_EXPORT iERR ion_int_from_hex_string (ION_INT *iint, const iSTRING p_str);
152 ION_API_EXPORT iERR ion_int_from_binary_string(ION_INT *iint, const iSTRING p_str);
153 ION_API_EXPORT iERR ion_int_from_chars (ION_INT *iint, const char *p_chars, SIZE char_limit);
154 ION_API_EXPORT iERR ion_int_from_hex_chars (ION_INT *iint, const char *p_chars, SIZE char_limit);
155 ION_API_EXPORT iERR ion_int_from_binary_chars(ION_INT *iint, const char *p_chars, SIZE char_limit);
156 ION_API_EXPORT iERR ion_int_from_bytes (ION_INT *iint, BYTE *buf, SIZE limit);
157 ION_API_EXPORT iERR ion_int_from_abs_bytes (ION_INT *iint, BYTE *buf, SIZE limit, BOOL is_negative);
158 ION_API_EXPORT iERR ion_int_from_long (ION_INT *iint, int64_t value);
159 
163 ION_API_EXPORT iERR ion_int_from_decimal (ION_INT *iint, const decQuad *p_value, decContext *context);
164 
165 ION_API_EXPORT iERR ion_int_char_length (ION_INT *iint, SIZE *p_len);
166 ION_API_EXPORT iERR ion_int_to_char (ION_INT *iint, BYTE *p_str, SIZE len, SIZE *p_written);
167 ION_API_EXPORT iERR ion_int_to_string (ION_INT *iint, hOWNER owner, iSTRING p_str);
168 
169 ION_API_EXPORT iERR ion_int_byte_length (ION_INT *iint, SIZE *p_byte_length);
170 ION_API_EXPORT iERR ion_int_to_bytes (ION_INT *iint, SIZE starting_int_byte_offset, BYTE *buffer, SIZE buffer_length, SIZE *bytes_written);
171 ION_API_EXPORT iERR ion_int_abs_bytes_length(ION_INT *iint, SIZE *p_byte_length);
172 ION_API_EXPORT iERR ion_int_to_abs_bytes (ION_INT *iint, SIZE starting_int_byte_offset, BYTE *buffer, SIZE buffer_length, SIZE *bytes_written);
173 ION_API_EXPORT iERR ion_int_to_int64 (ION_INT *iint, int64_t *p_int64);
174 ION_API_EXPORT iERR ion_int_to_int32 (ION_INT *iint, int32_t *p_int32);
175 
179 ION_API_EXPORT iERR ion_int_to_decimal (ION_INT *iint, decQuad *p_quad, decContext *context);
180 
182 // internal functions
184 void _ion_int_dump_quad(decQuad *quad, int64_t expected);
185 int _ion_int_init_globals(void);
186 
187 iERR _ion_int_from_decimal_number(ION_INT *iint, const decNumber *p_value, decContext *context);
188 iERR _ion_int_to_decimal_number(ION_INT *iint, decNumber *p_value, decContext *context);
189 
190 iERR _ion_int_validate_arg(const ION_INT *iint);
191 iERR _ion_int_validate_arg_with_ptr(const ION_INT *iint, const void *ptr);
192 iERR _ion_int_validate_non_null_arg_with_ptr(const ION_INT *iint, const void *ptr);
193 
194 void _ion_int_init(ION_INT *iint, void *owner);
195 iERR _ion_int_zero(ION_INT *iint);
196 void * _ion_int_realloc_helper(void *value, SIZE old_len, void *owner, SIZE new_len);
197 iERR _ion_int_extend_digits(ION_INT *iint, SIZE digits_needed, BOOL zero_fill);
198 II_DIGIT *_ion_int_buffer_temp_copy( II_DIGIT *orig_digits, SIZE len, II_DIGIT *cache_buffer, SIZE cache_len);
199 II_DIGIT *_ion_int_buffer_temp_copy( II_DIGIT *orig_digits, SIZE len, II_DIGIT *cache_buffer, SIZE cache_len);
200 void _ion_int_free_temp(II_DIGIT *temp_buffer, II_DIGIT *cache_buffer);
201 
202 BOOL _ion_int_from_bytes_helper(ION_INT *iint, BYTE *buf, SIZE byte_idx, SIZE limit, BOOL invert, BOOL includes_sign_byte);
203 iERR _ion_int_from_chars_helper(ION_INT *iint, const char *str, SIZE len);
204 iERR _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);
205 iERR _ion_int_from_hex_chars_helper(ION_INT *iint, const char *str, SIZE len);
206 iERR _ion_int_from_binary_chars_helper(ION_INT *iint, const char *str, SIZE len);
207 
208 BOOL _ion_int_is_null_helper(const ION_INT *iint);
209 BOOL _ion_int_is_zero(const ION_INT *iint);
210 BOOL _ion_int_is_zero_bytes(const II_DIGIT *digits, SIZE len);
211 
212 SIZE _ion_int_highest_bit_set_helper(const ION_INT *iint);
213 
214 SIZE _ion_int_get_char_len_helper(const ION_INT *iint);
215 iERR _ion_int_to_string_helper(ION_INT *iint, char *strbuf, SIZE buflen, SIZE *p_written);
216 
217 BOOL _ion_int_is_high_bytes_high_bit_set_helper(const ION_INT *iint, SIZE abs_byte_count);
218 SIZE _ion_int_bytes_length_helper(const ION_INT *iint);
219 iERR _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 
221 SIZE _ion_int_abs_bytes_length_helper(const ION_INT *iint);
222 SIZE _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 
225 iERR _ion_int_to_int64_helper(ION_INT *iint, int64_t *p_int64);
226 
227 iERR _ion_int_add_digit(II_DIGIT *digits, SIZE digit_count, II_DIGIT value);
228 iERR _ion_int_sub_digit(II_DIGIT *digits, SIZE digit_count, II_DIGIT value);
229 /* not used
230 iERR _ion_int_multiply_by_digit(II_DIGIT *digits, SIZE digit_count, II_DIGIT value);
231 */
232 iERR _ion_int_multiply_and_add(II_DIGIT *digits, SIZE digit_count, II_DIGIT mult_value, II_DIGIT add_value);
233 iERR _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