takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers strconv.c Source File

strconv.c

00001 /*
00002  * Copyright (c) 2018 ARM Limited. All rights reserved.
00003  * SPDX-License-Identifier: Apache-2.0
00004  * Licensed under the Apache License, Version 2.0 (the License); you may
00005  * not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  * http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
00012  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 #include <string.h>
00017 #include <stdlib.h>
00018 #include <stdio.h>
00019 #include <ctype.h>
00020 
00021 #include "ip6string.h"
00022 #include "strconv.h"
00023 
00024 
00025 int8_t strtohex(uint8_t *out, const char *str, int8_t max_length)
00026 {
00027     int8_t i = 0;
00028     char *rd = (char *)str;
00029     uint8_t *wr = out;
00030     while (*rd != 0) {
00031         if (i > max_length) {
00032             break;
00033         }
00034         *wr++ = strtoul(rd, &rd, 16);
00035         while (!isxdigit((int)*rd) && *rd != 0) {
00036             rd++; //skip some invalid characters
00037         }
00038         i++;
00039     }
00040     return i;
00041 }
00042 
00043 int hexstr_to_bytes_inplace(char *str)
00044 {
00045     int16_t len, i, j;
00046     if (str == NULL) {
00047         return -1;
00048     }
00049     len = strlen(str);
00050     if (len < 2 || (len + 1) % 3 != 0) {
00051         return -1;
00052     }
00053     for (i = 0, j = 0; i < len; i += 3, ++j) {
00054         str[j] = (char)strtol(str + i, 0, 16);
00055     }
00056     return j;
00057 }
00058 
00059 // convert hex string (eg. "76 ab ff") to binary array
00060 int string_to_bytes(const char *str, uint8_t *buf, int bytes)
00061 {
00062     int len = strlen(str);
00063     if (len <= (3 * bytes - 1)) {
00064         int i;
00065         for (i = 0; i < bytes; i++) {
00066             if (i * 3 < len) {
00067                 buf[i] = (uint8_t)strtoul(str + i * 3, 0, 16);
00068             } else {
00069                 buf[i] = 0;
00070             }
00071         }
00072         return 0;
00073     }
00074     return -1;
00075 }
00076 
00077 int16_t hextostr(const uint8_t *buf, uint16_t buf_length, char *out, int16_t out_length, char delimiter)
00078 {
00079     int16_t outLeft = out_length;
00080     int16_t arrLeft = buf_length;
00081     const uint8_t *rd = buf;
00082     int retcode = 0;
00083     char *wr = out;
00084     while (arrLeft > 0 && outLeft > 0) {
00085         retcode = snprintf(wr, outLeft, "%02x", *rd);
00086 
00087         if (retcode <= 0 || retcode >= outLeft) {
00088             break;
00089         }
00090         outLeft -= retcode;
00091         wr += retcode;
00092         arrLeft --;
00093         rd++;
00094         if (delimiter && arrLeft > 0 && outLeft > 0) {
00095             *wr++ = delimiter;
00096             outLeft--;
00097             *wr = 0;
00098         }
00099     }
00100     return (int16_t)(wr - out);
00101 }
00102 int replace_hexdata(char *str)
00103 {
00104     char *ptr = str;
00105     if (str == NULL) {
00106         return 0;
00107     }
00108     while (*ptr) {
00109         if (ptr[0] == '\\') {
00110             if (ptr[1] == 'n') {
00111                 ptr[0] = 0x0a;
00112                 memmove(ptr + 1, ptr + 2, strlen(ptr + 2) + 1);
00113             } else if (ptr[1] == 'r') {
00114                 ptr[0] = 0x0d;
00115                 memmove(ptr + 1, ptr + 2, strlen(ptr + 2) + 1);
00116             } else if (ptr[1] == 'x') {
00117                 char *end;
00118                 ptr[0] = (char)strtoul(ptr + 2, &end, 16);
00119                 memmove(ptr + 1, end, strlen(end) + 1);
00120             } else if (isdigit((int)ptr[1])) {
00121                 char *end;
00122                 ptr[0] = strtoul(ptr + 1, &end, 10);
00123                 memmove(ptr + 1, end, strlen(end) + 1);
00124             }
00125         }
00126         ptr++;
00127     }
00128     return ptr - str;
00129 }
00130 bool is_visible(uint8_t *buf, int len)
00131 {
00132     while (len--) {
00133         if (!isalnum(*buf) && *buf != ' ') {
00134             return false;
00135         }
00136         buf++;
00137     }
00138     return true;
00139 }
00140 
00141 char *strdupl(const char *str)
00142 {
00143     if (!str) {
00144         return NULL;
00145     }
00146     char *p = malloc(strlen(str) + 1);
00147     if (!p) {
00148         return p;
00149     }
00150     strcpy(p, str);
00151     return p;
00152 }
00153 int strnlen_(const char *s, int n)
00154 {
00155     char *end = memchr(s, 0, n);
00156     return end ? end - s : n;
00157 }
00158 char *strndupl(const char *s, int n)
00159 {
00160     char *p = NULL;
00161     int len = strnlen_(s, n);
00162     p = malloc(len + 1);
00163     if (!p) {
00164         return p;
00165     }
00166     p[len] = 0;
00167     return memcpy(p, s, len);
00168 }
00169 int strnicmp_(char const *a, char const *b, int n)
00170 {
00171     for (; (n > 0 && *a != 0 && *b != 0) ; a++, b++, n--) {
00172         int d = tolower((int) * a) - tolower((int) * b);
00173         if (d != 0 || !*a) {
00174             return d;
00175         }
00176     }
00177     return 0;
00178 }
00179 
00180 
00181 /* HELPING PRINT FUNCTIONS for cmd_printf */
00182 
00183 static inline uint8_t context_split_mask(uint_fast8_t split_value)
00184 {
00185     return (uint8_t) - (0x100u >> split_value);
00186 }
00187 
00188 static uint8_t *bitcopy(uint8_t *restrict dst, const uint8_t *restrict src, uint_fast8_t bits)
00189 {
00190     uint_fast8_t bytes = bits / 8;
00191     bits %= 8;
00192 
00193     if (bytes) {
00194         dst = (uint8_t *) memcpy(dst, src, bytes) + bytes;
00195         src += bytes;
00196     }
00197 
00198     if (bits) {
00199         uint_fast8_t split_bit = context_split_mask(bits);
00200         *dst = (*src & split_bit) | (*dst & ~ split_bit);
00201     }
00202 
00203     return dst;
00204 }
00205 
00206 char tmp_print_buffer[128] = {0};
00207 
00208 char *print_ipv6(const void *addr_ptr)
00209 {
00210     ip6tos(addr_ptr, tmp_print_buffer);
00211     return tmp_print_buffer;
00212 }
00213 char *print_ipv6_prefix(const uint8_t *prefix, uint8_t prefix_len)
00214 {
00215     char *str = tmp_print_buffer;
00216     int retval;
00217     char tmp[40];
00218     uint8_t addr[16] = {0};
00219 
00220     if (prefix_len != 0) {
00221         if (prefix == NULL || prefix_len > 128) {
00222             return "<err>";
00223         }
00224         bitcopy(addr, prefix, prefix_len);
00225     }
00226 
00227     ip6tos(addr, tmp);
00228     retval = snprintf(str, 128, "%s/%u", tmp, prefix_len);
00229     if (retval <= 0) {
00230         return "";
00231     }
00232     return str;
00233 }
00234 char *print_array(const uint8_t *buf, uint16_t len)
00235 {
00236     int16_t retcode = hextostr(buf, len, tmp_print_buffer, 128, ':');
00237     if (retcode > 0) {
00238         //yeah, something is converted
00239     }
00240     return tmp_print_buffer;
00241 }
00242