gearmulator

Emulation of classic VA synths of the late 90s/2000s that are based on Motorola 56300 family DSPs
Log | Files | Refs | Submodules | README | LICENSE

pstrtoi.cxx (2685B)


      1 /*
      2  *
      3  *  C++ Portable Types Library (PTypes)
      4  *  Version 2.1.1  Released 27-Jun-2007
      5  *
      6  *  Copyright (C) 2001-2007 Hovik Melikyan
      7  *
      8  *  http://www.melikyan.com/ptypes/
      9  *
     10  */
     11 
     12 #include <string.h>
     13 
     14 #include "ptypes.h"
     15 
     16 
     17 namespace ptypes {
     18 
     19 
     20 static void throw_conv(const char* p);
     21 static void throw_overflow(const char* p);
     22 
     23 
     24 large ptdecl stringtoi(const char* p)
     25 {
     26     if (p == 0)
     27         return -1;
     28     if (*p == 0)
     29         return -1;
     30 
     31     large r = 0;
     32     do 
     33     {
     34         char c = *p++;
     35         if (c < '0' || c > '9')
     36             return -1;              // invalid character
     37         large t = r * 10;
     38         if (t < r)
     39             return -1;              // overflow
     40         t += c - '0';
     41         if (t < r)
     42             return -1;              // overflow
     43         r = t;
     44     } while (*p != 0);
     45 
     46     return r;
     47 }
     48 
     49 
     50 econv::~econv()
     51 {
     52 }
     53 
     54 
     55 ularge ptdecl stringtoue(const char* str, int base)
     56 {
     57     if (str == 0)
     58         throw_conv(str);
     59     if (*str == 0 || base < 2 || base > 64)
     60         throw_conv(str);
     61 
     62     const char* p = str;
     63     ularge result = 0;
     64 
     65     do 
     66     {
     67         int c = *p++;
     68 
     69         if (c >= 'a')
     70         {
     71             // for the numeration bases that use '.', '/', digits and
     72             // uppercase letters the letter case is insignificant.
     73             if (base <= 38)
     74                 c -= 'a' - '9' - 1;
     75             else  // others use both upper and lower case letters
     76                 c -= ('a' - 'Z' - 1) + ('A' - '9' - 1);
     77         }
     78         else if (c > 'Z')
     79             throw_conv(str);
     80         else if (c >= 'A')
     81             c -= 'A' - '9' - 1;
     82         else if (c > '9')
     83             throw_conv(str);
     84 
     85         c -= (base > 36) ? '.' : '0';
     86         if (c < 0 || c >= base)
     87             throw_conv(str);
     88 
     89         ularge t = result * uint(base);
     90         if (t / base != result)
     91             throw_overflow(str);
     92         result = t;
     93         t = result + uint(c);
     94         if (t < result)
     95             throw_overflow(str);
     96         result = t;
     97     } while (*p != 0);
     98 
     99     return result;
    100 }
    101 
    102 
    103 large ptdecl stringtoie(const char* str)
    104 {
    105     if (str == 0)
    106         throw_conv(str);
    107     bool neg = *str == '-';
    108     ularge result = stringtoue(str + int(neg), 10);
    109     if (result > (ularge(LARGE_MAX) + uint(neg)))
    110         throw_overflow(str);
    111     if (neg)
    112         return - large(result);
    113     else
    114         return large(result);
    115 }
    116 
    117 
    118 #ifdef _MSC_VER
    119 // disable "unreachable code" warning for throw (known compiler bug)
    120 #  pragma warning (disable: 4702)
    121 #endif
    122 
    123 static void throw_conv(const char* p)
    124 {
    125     throw new econv("Invalid number: '" + string(p) + '\'');
    126 }
    127 
    128 
    129 static void throw_overflow(const char* p)
    130 {
    131     throw new econv("Out of range: '" + string(p) + '\'');
    132 }
    133 
    134 
    135 }
    136