reSIProcate/stack  9694
testConvertRaw.cxx
Go to the documentation of this file.
00001 #include <stdlib.h>
00002 #include <stdio.h>
00003 #include <sys/types.h>
00004 #include <unistd.h>
00005 #include <fcntl.h>
00006 #include <ctype.h>
00007 #include <string>
00008 
00009 const size_t indent = 4;
00010 
00011 class ArGen
00012 {
00013     public:
00014         ArGen(const char *arname = 0,
00015               const int arnum = 0,
00016               size_t wrapCol = 72);
00017         ~ArGen();
00018         void add(const unsigned char c);
00019         void add(const unsigned char * buf, size_t sz);
00020         void end();
00021         int outputDef(int fd);
00022     private:
00023         void addRaw(const unsigned char c);
00024         void addRaw(const char* str);
00025         std::string code;
00026         size_t mColumn;
00027         size_t mNcols;
00028 };
00029 
00030 static std::string
00031 toString(int v )
00032 {
00033     std::string s;
00034     bool b = false;
00035     for( int i = 1000000; i > 0 ; i/=10)
00036     {
00037         int p = v/i;
00038         if (b = ( b || p || ( i == 1)))
00039             s += '0' + p;
00040         v = v % i;
00041     }
00042     return s;
00043 }
00044 
00045 ArGen::ArGen(const char *arname, int arnum, size_t wrapCol) :
00046     mColumn(0),
00047     mNcols(wrapCol)
00048 
00049 {
00050     if (!arname)
00051         arname = "data";
00052 
00053     code += "const char ";
00054     code += arname;
00055     if (arnum) code += toString(arnum);
00056     code += "[] = {\n";
00057 }
00058 
00059 
00060 
00061 void
00062 ArGen::addRaw(const unsigned char c)
00063 {
00064     code += c;
00065     ++mColumn;
00066 }
00067 
00068 void ArGen::addRaw(const char* s)
00069 {
00070     for(size_t i = 0 ; s[i] ; ++i)
00071         addRaw(s[i]);
00072 }
00073 
00075 void
00076 ArGen::add(const unsigned char c)
00077 {
00078     // take care of 1st part of line
00079     if (!mColumn)
00080         addRaw("        \"");
00081 
00082     // take care of switching modes and opening or closing any running
00083     // quotations.
00084 
00085     if (isalnum(c) || c == ' ' ||
00086         ( ispunct(c) && c != '\\' && c != '"' ))
00087     {
00088         addRaw(c);
00089     }
00090     else
00091     {
00092         static const char hexv[] ="0123456789abcdef";
00093         addRaw("\\x");
00094         addRaw(hexv[(c&0xf0)>>8]);
00095         addRaw(hexv[(c&0x0f)]);
00096     }
00097     if (mColumn > mNcols || c == 0x0a)
00098     {
00099         addRaw("\"\n");
00100         mColumn = 0;
00101     }
00102 }
00103 
00104 void
00105 ArGen::add(const unsigned char *c , size_t sz)
00106 {
00107     for(size_t i = 0 ; i < sz ; ++i)
00108         add(c[i]);
00109 }
00110 
00111 ArGen::~ArGen() {}
00112 
00113 
00114 void
00115 ArGen::end()
00116 {
00117 
00118     code += '\n';
00119     code += "};\n";
00120 }
00121 
00122 int
00123 ArGen::outputDef(int fd)
00124 {
00125     return write(fd,code.data(),code.size());
00126 }
00127 
00128 void
00129 dumpraw(const char *path, const char * basename, int arNo)
00130 {
00131     
00132     if (access(path,R_OK))
00133     {
00134         perror(path);
00135         return;
00136     }
00137     int fd = open(path,O_RDONLY);
00138     if (fd < 0)
00139     {
00140         perror(path);
00141         return;
00142     }
00143     int hdr = 0;
00144     int s;
00145     char unsigned buf[16 * 1024];
00146     const int bsz = sizeof(buf)/sizeof(*buf);
00147     const int nCols = 8;
00148     int col = 0;
00149     ArGen cg(basename,arNo);
00150     while((s=read(fd,buf,bsz)) > 0)
00151     {
00152         cg.add(buf,s);
00153     }
00154     cg.end();
00155 
00156     if (s < 0)
00157     {
00158         perror(path);
00159         return;
00160     }
00161     cg.outputDef(1);
00162 
00163     return;
00164 }
00165 
00166 const char * pName = 0;
00167 int
00168 usage()
00169 {
00170     printf("usage: %s [-n arraybasename] file ...\n",pName);
00171 }
00172 int
00173 main(int argc, char * argv[])
00174 {
00175     pName = *argv;
00176     const char * basename = 0;
00177     int basearg = 1;
00178     if (argc < 2) return usage();
00179     if (argv[1][0] == '-' &&
00180         argv[1][1] == 'n')
00181     {
00182         if (argc < 4) return usage();
00183         basename = argv[2];
00184         basearg = 3;
00185     }
00186     for (int i = basearg ; i < argc ; ++i )
00187         dumpraw(argv[i],basename,i-basearg);
00188     return 0;
00189 }
00190 
00191 /* ====================================================================
00192  * The Vovida Software License, Version 1.0 
00193  * 
00194  * Copyright (c) 2000-2005 Vovida Networks, Inc.  All rights reserved.
00195  * 
00196  * Redistribution and use in source and binary forms, with or without
00197  * modification, are permitted provided that the following conditions
00198  * are met:
00199  * 
00200  * 1. Redistributions of source code must retain the above copyright
00201  *    notice, this list of conditions and the following disclaimer.
00202  * 
00203  * 2. Redistributions in binary form must reproduce the above copyright
00204  *    notice, this list of conditions and the following disclaimer in
00205  *    the documentation and/or other materials provided with the
00206  *    distribution.
00207  * 
00208  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00209  *    and "Vovida Open Communication Application Library (VOCAL)" must
00210  *    not be used to endorse or promote products derived from this
00211  *    software without prior written permission. For written
00212  *    permission, please contact vocal@vovida.org.
00213  *
00214  * 4. Products derived from this software may not be called "VOCAL", nor
00215  *    may "VOCAL" appear in their name, without prior written
00216  *    permission of Vovida Networks, Inc.
00217  * 
00218  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00219  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00220  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00221  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00222  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00223  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00224  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00225  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00226  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00227  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00228  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00229  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00230  * DAMAGE.
00231  * 
00232  * ====================================================================
00233  * 
00234  * This software consists of voluntary contributions made by Vovida
00235  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00236  * Inc.  For more information on Vovida Networks, Inc., please see
00237  * <http://www.vovida.org/>.
00238  *
00239  */
00240