]> git.sur5r.net Git - openocd/blobdiff - src/helper/binarybuffer.c
help/options.c: add error handling for -d arg
[openocd] / src / helper / binarybuffer.c
index b3e44916aa4d44de39f39750226d2bb9c5bb4462..76f657f8df8eb9b88758ff80b29b6370ee092e12 100644 (file)
@@ -16,9 +16,7 @@
  *   GNU General Public License for more details.                          *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
  ***************************************************************************/
 
 #ifdef HAVE_CONFIG_H
@@ -47,6 +45,11 @@ static const unsigned char bit_reverse_table256[] = {
        0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
 };
 
+static const char hex_digits[] = {
+       '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+       'a', 'b', 'c', 'd', 'e', 'f'
+};
+
 void *buf_cpy(const void *from, void *_to, unsigned size)
 {
        if (NULL == from || NULL == _to)
@@ -148,7 +151,7 @@ void *buf_set_buf(const void *_src, unsigned src_start,
        if ((sq == 0) && (dq == 0) &&  (lq == 0)) {
                for (i = 0; i < lb; i++)
                        *dst++ = *src++;
-               return (uint8_t *)_dst;
+               return _dst;
        }
 
        /* fallback to slow bit copy */
@@ -167,7 +170,7 @@ void *buf_set_buf(const void *_src, unsigned src_start,
                }
        }
 
-       return (uint8_t *)_dst;
+       return _dst;
 }
 
 uint32_t flip_u32(uint32_t value, unsigned int num)
@@ -231,7 +234,7 @@ char *buf_to_str(const void *_buf, unsigned buf_len, unsigned radix)
                }
        }
 
-       const char *DIGITS = "0123456789ABCDEF";
+       const char * const DIGITS = "0123456789ABCDEF";
        for (unsigned j = 0; j < str_len; j++)
                str[j] = DIGITS[(int)str[j]];
 
@@ -371,29 +374,91 @@ void bit_copy_discard(struct bit_copy_queue *q)
        }
 }
 
-int unhexify(char *bin, const char *hex, int count)
+/**
+ * Convert a string of hexadecimal pairs into its binary
+ * representation.
+ *
+ * @param[out] bin Buffer to store binary representation. The buffer size must
+ *                 be at least @p count.
+ * @param[in] hex String with hexadecimal pairs to convert into its binary
+ *                representation.
+ * @param[in] count Number of hexadecimal pairs to convert.
+ *
+ * @return The number of converted hexadecimal pairs.
+ */
+size_t unhexify(uint8_t *bin, const char *hex, size_t count)
 {
-       int i, tmp;
+       size_t i;
+       char tmp;
+
+       if (!bin || !hex)
+               return 0;
+
+       memset(bin, 0, count);
 
-       for (i = 0; i < count; i++) {
-               if (sscanf(hex + (2 * i), "%02x", &tmp) != 1)
-                       return i;
-               bin[i] = tmp;
+       for (i = 0; i < 2 * count; i++) {
+               if (hex[i] >= 'a' && hex[i] <= 'f')
+                       tmp = hex[i] - 'a' + 10;
+               else if (hex[i] >= 'A' && hex[i] <= 'F')
+                       tmp = hex[i] - 'A' + 10;
+               else if (hex[i] >= '0' && hex[i] <= '9')
+                       tmp = hex[i] - '0';
+               else
+                       return i / 2;
+
+               bin[i / 2] |= tmp << (4 * ((i + 1) % 2));
        }
 
+       return i / 2;
+}
+
+/**
+ * Convert binary data into a string of hexadecimal pairs.
+ *
+ * @param[out] hex Buffer to store string of hexadecimal pairs. The buffer size
+ *                 must be at least @p length.
+ * @param[in] bin Buffer with binary data to convert into hexadecimal pairs.
+ * @param[in] count Number of bytes to convert.
+ * @param[in] length Maximum number of characters, including null-terminator,
+ *                   to store into @p hex.
+ *
+ * @returns The length of the converted string excluding null-terminator.
+ */
+size_t hexify(char *hex, const uint8_t *bin, size_t count, size_t length)
+{
+       size_t i;
+       uint8_t tmp;
+
+       if (!length)
+               return 0;
+
+       for (i = 0; i < length - 1 && i < 2 * count; i++) {
+               tmp = (bin[i / 2] >> (4 * ((i + 1) % 2))) & 0x0f;
+               hex[i] = hex_digits[tmp];
+       }
+
+       hex[i] = 0;
+
        return i;
 }
 
-int hexify(char *hex, const char *bin, int count, int out_maxlen)
+void buffer_shr(void *_buf, unsigned buf_len, unsigned count)
 {
-       int i, cmd_len = 0;
+       unsigned i;
+       unsigned char *buf = _buf;
+       unsigned bytes_to_remove;
+       unsigned shift;
 
-       /* May use a length, or a null-terminated string as input. */
-       if (count == 0)
-               count = strlen(bin);
+       bytes_to_remove = count / 8;
+       shift = count - (bytes_to_remove * 8);
 
-       for (i = 0; i < count; i++)
-               cmd_len += snprintf(hex + cmd_len, out_maxlen - cmd_len, "%02x", bin[i] & 0xff);
+       for (i = 0; i < (buf_len - 1); i++)
+               buf[i] = (buf[i] >> shift) | ((buf[i+1] << (8 - shift)) & 0xff);
 
-       return cmd_len;
+       buf[(buf_len - 1)] = buf[(buf_len - 1)] >> shift;
+
+       if (bytes_to_remove) {
+               memmove(buf, &buf[bytes_to_remove], buf_len - bytes_to_remove);
+               memset(&buf[buf_len - bytes_to_remove], 0, bytes_to_remove);
+       }
 }