1*5c4dab75SAndroid Build Coastguard Worker /*
2*5c4dab75SAndroid Build Coastguard Worker * Copyright (C) 2017 The Android Open Source Project
3*5c4dab75SAndroid Build Coastguard Worker *
4*5c4dab75SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*5c4dab75SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*5c4dab75SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*5c4dab75SAndroid Build Coastguard Worker *
8*5c4dab75SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*5c4dab75SAndroid Build Coastguard Worker *
10*5c4dab75SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*5c4dab75SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*5c4dab75SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*5c4dab75SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*5c4dab75SAndroid Build Coastguard Worker * limitations under the License.
15*5c4dab75SAndroid Build Coastguard Worker *
16*5c4dab75SAndroid Build Coastguard Worker */
17*5c4dab75SAndroid Build Coastguard Worker
18*5c4dab75SAndroid Build Coastguard Worker #include "buffer.h"
19*5c4dab75SAndroid Build Coastguard Worker
buffer_init(struct Buffer * b,uint32_t len)20*5c4dab75SAndroid Build Coastguard Worker bool buffer_init(struct Buffer *b, uint32_t len) {
21*5c4dab75SAndroid Build Coastguard Worker if (!b)
22*5c4dab75SAndroid Build Coastguard Worker return false;
23*5c4dab75SAndroid Build Coastguard Worker b->buffer = calloc(len, 1);
24*5c4dab75SAndroid Build Coastguard Worker if (!b->buffer)
25*5c4dab75SAndroid Build Coastguard Worker return false;
26*5c4dab75SAndroid Build Coastguard Worker b->len = 0;
27*5c4dab75SAndroid Build Coastguard Worker b->size = len;
28*5c4dab75SAndroid Build Coastguard Worker return true;
29*5c4dab75SAndroid Build Coastguard Worker }
30*5c4dab75SAndroid Build Coastguard Worker
buffer_free(struct Buffer * b)31*5c4dab75SAndroid Build Coastguard Worker void buffer_free(struct Buffer *b) {
32*5c4dab75SAndroid Build Coastguard Worker if (b && b->buffer)
33*5c4dab75SAndroid Build Coastguard Worker free(b->buffer);
34*5c4dab75SAndroid Build Coastguard Worker }
35*5c4dab75SAndroid Build Coastguard Worker
buffer_read_hex(struct Buffer * b,FILE * fp,bool consume_newline)36*5c4dab75SAndroid Build Coastguard Worker bool buffer_read_hex(struct Buffer *b, FILE *fp, bool consume_newline) {
37*5c4dab75SAndroid Build Coastguard Worker int offset;
38*5c4dab75SAndroid Build Coastguard Worker uint32_t i;
39*5c4dab75SAndroid Build Coastguard Worker
40*5c4dab75SAndroid Build Coastguard Worker if (feof(fp))
41*5c4dab75SAndroid Build Coastguard Worker return false;
42*5c4dab75SAndroid Build Coastguard Worker /* Consume leading whitespace. */
43*5c4dab75SAndroid Build Coastguard Worker while (!feof(fp)) {
44*5c4dab75SAndroid Build Coastguard Worker char c = fgetc(fp);
45*5c4dab75SAndroid Build Coastguard Worker if (!consume_newline && (c == 0x0d || c == 0x0a)) {
46*5c4dab75SAndroid Build Coastguard Worker return false;
47*5c4dab75SAndroid Build Coastguard Worker }
48*5c4dab75SAndroid Build Coastguard Worker if (!isspace(c)) {
49*5c4dab75SAndroid Build Coastguard Worker ungetc(c, fp);
50*5c4dab75SAndroid Build Coastguard Worker break;
51*5c4dab75SAndroid Build Coastguard Worker }
52*5c4dab75SAndroid Build Coastguard Worker }
53*5c4dab75SAndroid Build Coastguard Worker
54*5c4dab75SAndroid Build Coastguard Worker for (; !feof(fp) && b->len < b->size; ++b->len) {
55*5c4dab75SAndroid Build Coastguard Worker b->buffer[b->len] = fgetc(fp);
56*5c4dab75SAndroid Build Coastguard Worker if (!isalnum(b->buffer[b->len])) {
57*5c4dab75SAndroid Build Coastguard Worker ungetc(b->buffer[b->len], fp);
58*5c4dab75SAndroid Build Coastguard Worker break;
59*5c4dab75SAndroid Build Coastguard Worker }
60*5c4dab75SAndroid Build Coastguard Worker }
61*5c4dab75SAndroid Build Coastguard Worker if (b->len == 0)
62*5c4dab75SAndroid Build Coastguard Worker return false;
63*5c4dab75SAndroid Build Coastguard Worker
64*5c4dab75SAndroid Build Coastguard Worker for (offset = 0, i = 0; offset < (int)b->len && i < b->size; ++i) {
65*5c4dab75SAndroid Build Coastguard Worker int last_offset = offset;
66*5c4dab75SAndroid Build Coastguard Worker if (sscanf((char *)b->buffer + offset, "%2hhx%n", &b->buffer[i], &offset) !=
67*5c4dab75SAndroid Build Coastguard Worker 1)
68*5c4dab75SAndroid Build Coastguard Worker break;
69*5c4dab75SAndroid Build Coastguard Worker offset += last_offset;
70*5c4dab75SAndroid Build Coastguard Worker if (offset == 0)
71*5c4dab75SAndroid Build Coastguard Worker break;
72*5c4dab75SAndroid Build Coastguard Worker }
73*5c4dab75SAndroid Build Coastguard Worker b->len = i;
74*5c4dab75SAndroid Build Coastguard Worker return true;
75*5c4dab75SAndroid Build Coastguard Worker }
76*5c4dab75SAndroid Build Coastguard Worker
buffer_dump(const struct Buffer * b,const char * prefix,const char * name,uint32_t limit,FILE * fp)77*5c4dab75SAndroid Build Coastguard Worker void buffer_dump(const struct Buffer *b, const char *prefix, const char *name,
78*5c4dab75SAndroid Build Coastguard Worker uint32_t limit, FILE *fp) {
79*5c4dab75SAndroid Build Coastguard Worker fprintf(fp, "%s%s {\n", prefix, name);
80*5c4dab75SAndroid Build Coastguard Worker fprintf(fp, "%s .length = %u\n", prefix, b->len);
81*5c4dab75SAndroid Build Coastguard Worker fprintf(fp, "%s .size = %u\n", prefix, b->size);
82*5c4dab75SAndroid Build Coastguard Worker fprintf(fp, "%s .buffer = {\n", prefix);
83*5c4dab75SAndroid Build Coastguard Worker fprintf(fp, "%s ", prefix);
84*5c4dab75SAndroid Build Coastguard Worker for (uint32_t i = 0; i < b->len; ++i) {
85*5c4dab75SAndroid Build Coastguard Worker if (i > 15 && i % 16 == 0) {
86*5c4dab75SAndroid Build Coastguard Worker fprintf(fp, "\n%s ", prefix);
87*5c4dab75SAndroid Build Coastguard Worker }
88*5c4dab75SAndroid Build Coastguard Worker if (i > limit) {
89*5c4dab75SAndroid Build Coastguard Worker fprintf(fp, ". . .");
90*5c4dab75SAndroid Build Coastguard Worker break;
91*5c4dab75SAndroid Build Coastguard Worker }
92*5c4dab75SAndroid Build Coastguard Worker fprintf(fp, "%.2x ", b->buffer[i]);
93*5c4dab75SAndroid Build Coastguard Worker }
94*5c4dab75SAndroid Build Coastguard Worker fprintf(fp, "\n%s}\n", prefix);
95*5c4dab75SAndroid Build Coastguard Worker }
96