binPrintf.cpp
Go to the documentation of this file.
00001 /*
00002   Copyright 2001 Georges Menie
00003   https://www.menie.org/georges/embedded/small_printf_source_code.html
00004 
00005   This program is free software; you can redistribute it and/or modify
00006   it under the terms of the GNU Lesser General Public License as published by
00007   the Free Software Foundation; either version 2 of the License, or
00008   (at your option) any later version.
00009 
00010   This program is distributed in the hope that it will be useful,
00011   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013   GNU Lesser General Public License for more details.
00014 
00015   You should have received a copy of the GNU Lesser General Public License
00016   along with this program; if not, write to the Free Software
00017   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 */
00019 
00020 #include "sick_scan/binPrintf.hpp"
00021 #include <stdio.h>
00022 #define BIN_SPRINTF_MAX_LEN (10240)
00023 static void binPrintchar(char **str, int c)
00024 {
00025         extern int putchar(int c);
00026         if (str) {
00027                 **str = c;
00028                 ++(*str);
00029         }
00030         else (void)putchar(c);
00031 }
00032 
00033 #define PAD_RIGHT 1
00034 #define PAD_ZERO 2
00035 
00036 static int binPrints(char **out, const char *string, int width, int pad)
00037 {
00038         register int pc = 0, padchar = ' ';
00039 
00040         if (width > 0) {
00041                 register int len = 0;
00042                 register const char *ptr;
00043                 for (ptr = string; *ptr; ++ptr) ++len;
00044                 if (len >= width) width = 0;
00045                 else width -= len;
00046                 if (pad & PAD_ZERO) padchar = '0';
00047         }
00048         if (!(pad & PAD_RIGHT)) {
00049                 for ( ; width > 0; --width) {
00050                         binPrintchar (out, padchar);
00051                         ++pc;
00052                 }
00053         }
00054         for ( ; *string ; ++string) {
00055                 binPrintchar (out, *string);
00056                 ++pc;
00057         }
00058         for ( ; width > 0; --width) {
00059                 binPrintchar (out, padchar);
00060                 ++pc;
00061         }
00062 
00063         return pc;
00064 }
00065 
00066 /* the following should be enough for 32 bit int */
00067 #define PRINT_BUF_LEN 12
00068 
00069 static int binPrinti(char **out, int i, int b, int sg, int width, int pad, int letbase)
00070 {
00071         char print_buf[PRINT_BUF_LEN];
00072         register char *s;
00073         register int t, neg = 0, pc = 0;
00074         register unsigned int u = i;
00075 
00076         if (b == 1)
00077         {
00078                 int cnt = 0;
00079                 while (width > 0)
00080                 {
00081                         ++pc;
00082                         ++cnt;
00083                         --width;
00084                         char ch = (char)(0xFF & (i >> (width * 8)));
00085                         binPrintchar(out, ch);
00086                 }
00087                 return(cnt);
00088         }
00089 
00090         if (i == 0) {
00091                 print_buf[0] = '0';
00092                 print_buf[1] = '\0';
00093                 return binPrints (out, print_buf, width, pad);
00094         }
00095 
00096         if (sg && b == 10 && i < 0) {
00097                 neg = 1;
00098                 u = -i;
00099         }
00100 
00101         s = print_buf + PRINT_BUF_LEN-1;
00102         *s = '\0';
00103 
00104         while (u) {
00105                 t = u % b;
00106                 if( t >= 10 )
00107                         t += letbase - '0' - 10;
00108                 *--s = t + '0';
00109                 u /= b;
00110         }
00111 
00112         if (neg) {
00113                 if( width && (pad & PAD_ZERO) ) {
00114                         binPrintchar (out, '-');
00115                         ++pc;
00116                         --width;
00117                 }
00118                 else {
00119                         *--s = '-';
00120                 }
00121         }
00122 
00123         return pc + binPrints (out, s, width, pad);
00124 }
00125 
00126 static int binPrint(char **out, long long *varg)
00127 {
00128         int width, pad;
00129         int pc = 0;
00130         char *format = (char *)(*varg++);
00131         char scr[2];
00132 
00133         for (; *format != 0; ++format) {
00134                 if (*format == '%') {
00135                         ++format;
00136                         width = pad = 0;
00137                         if (*format == '\0') break;
00138                         if (*format == '%') goto out;
00139                         if (*format == '-') {
00140                                 ++format;
00141                                 pad = PAD_RIGHT;
00142                         }
00143                         while (*format == '0') {
00144                                 ++format;
00145                                 pad |= PAD_ZERO;
00146                         }
00147                         for ( ; *format >= '0' && *format <= '9'; ++format) {
00148                                 width *= 10;
00149                                 width += *format - '0';
00150                         }
00151                         if( *format == 's' ) {
00152                                 register char *s = *((char **)varg++);
00153                                 pc += binPrints (out, s?s:"(null)", width, pad);
00154                                 continue;
00155                         }
00156                         if( *format == 'd' ) {
00157                                 pc += binPrinti (out, *varg++, 10, 1, width, pad, 'a');
00158                                 continue;
00159                         }
00160                         if( *format == 'x' ) {
00161                                 pc += binPrinti (out, *varg++, 16, 0, width, pad, 'a');
00162                                 continue;
00163                         }
00164                         if( *format == 'X' ) {
00165                                 pc += binPrinti (out, *varg++, 16, 0, width, pad, 'A');
00166                                 continue;
00167                         }
00168                         if (*format == 'y') {
00169                                 pc += binPrinti(out, *varg++, 1, 0, width, pad, 'A');
00170                                 continue;
00171                         }
00172                         if( *format == 'u' ) {
00173                                 pc += binPrinti (out, *varg++, 10, 0, width, pad, 'a');
00174                                 continue;
00175                         }
00176                         if( *format == 'c' ) {
00177                                 /* char are converted to int then pushed on the stack */
00178                                 scr[0] = *varg++;
00179                                 scr[1] = '\0';
00180                                 pc += binPrints (out, scr, width, pad);
00181                                 continue;
00182                         }
00183                 }
00184                 else {
00185                 out:
00186                         binPrintchar (out, *format);
00187                         ++pc;
00188                 }
00189         }
00190         if (out) **out = '\0';
00191         return pc;
00192 }
00193 
00194 /* assuming sizeof(void *) == sizeof(int) */
00195 
00196 int binPrintf(const char *format, ...)
00197 {
00198         long long *varg = (long long *)(&format);
00199         return binPrint(0, varg);
00200 }
00201 
00202 int binSprintf(char *out, const char *format, ...)
00203 {
00204         long long *varg = (long long *)(&format);
00205         return binPrint(&out, varg);
00206 }
00207 
00208 int binSprintfVec(std::vector<unsigned char>* outvec, const char *fmt, ...)
00209 {
00210         outvec->clear();
00211         char buffer[BIN_SPRINTF_MAX_LEN];
00212         char *bufferPtr = &(buffer[0]);
00213         void *tttt = &fmt;
00214         long long *varg = (long long *)(&fmt);
00215         int retCode = binPrint(&bufferPtr, varg);
00216         if (retCode > 0)
00217         {
00218                 for (int i = 0; i < retCode; i++)
00219                 {
00220                         outvec->push_back(buffer[i]);
00221                 }
00222         }
00223 
00224         return retCode;
00225 }
00226 
00227 
00228 std::string binDumpVecToString(std::vector<unsigned char>* outvec, bool appendReadableText /*= false*/)
00229 {
00230         std::string s;
00231         for (int i = 0; i < outvec->size(); i++)
00232         {
00233                 char szDummy[255] = { 0 };
00234                 sprintf(szDummy, "%02x ", (int)(0xFF & (*outvec)[i]));
00235                 s += szDummy;
00236         }
00237         if (appendReadableText)
00238         {
00239                 for (int i = 0; i < outvec->size(); i++)
00240                 {
00241                         char szDummy[255] = { 0 };
00242                         sprintf(szDummy, "%c", (*outvec)[i] < 0x20 ? '.' : (*outvec)[i]);
00243                         s += szDummy;
00244                 }
00245         }
00246         return(s);
00247 }
00248 
00249 
00250 


sick_scan
Author(s): Michael Lehning , Jochen Sprickerhof , Martin Günther
autogenerated on Tue Jul 9 2019 05:05:34