Moving in e2sim originally from it/test/simulators
[sim/e2-interface.git] / e2sim / ASN1c / asn_internal.c
1 /*****************************************************************************
2 #                                                                            *
3 # Copyright 2019 AT&T Intellectual Property                                  *
4 #                                                                            *
5 # Licensed under the Apache License, Version 2.0 (the "License");            *
6 # you may not use this file except in compliance with the License.           *
7 # You may obtain a copy of the License at                                    *
8 #                                                                            *
9 #      http://www.apache.org/licenses/LICENSE-2.0                            *
10 #                                                                            *
11 # Unless required by applicable law or agreed to in writing, software        *
12 # distributed under the License is distributed on an "AS IS" BASIS,          *
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
14 # See the License for the specific language governing permissions and        *
15 # limitations under the License.                                             *
16 #                                                                            *
17 ******************************************************************************/
18
19 #include <asn_internal.h>
20
21 ssize_t
22 asn__format_to_callback(int (*cb)(const void *, size_t, void *key), void *key,
23                         const char *fmt, ...) {
24     char scratch[64];
25     char *buf = scratch;
26     size_t buf_size = sizeof(scratch);
27     int wrote;
28     int cb_ret;
29
30     do {
31         va_list args;
32         va_start(args, fmt);
33
34         wrote = vsnprintf(buf, buf_size, fmt, args);
35         if(wrote < (ssize_t)buf_size) {
36             if(wrote < 0) {
37                 if(buf != scratch) FREEMEM(buf);
38                 va_end(args);
39                 return -1;
40             }
41             break;
42         }
43
44         buf_size <<= 1;
45         if(buf == scratch) {
46             buf = MALLOC(buf_size);
47             if(!buf) return -1;
48         } else {
49             void *p = REALLOC(buf, buf_size);
50             if(!p) {
51                 FREEMEM(buf);
52                 return -1;
53             }
54             buf = p;
55         }
56     } while(1);
57
58     cb_ret = cb(buf, wrote, key);
59     if(buf != scratch) FREEMEM(buf);
60     if(cb_ret < 0) {
61         return -1;
62     }
63
64     return wrote;
65 }
66