Main Page | Modules | Data Structures | Directories | File List | Data Fields | Globals

bits.c

Go to the documentation of this file.
00001 /*============================================================================*
00002  * FILE:                      bits.c
00003  *============================================================================*
00004  *
00005  *                      COPYRIGHT (C) 2006  BY
00006  *          CONDOR ENGINEERING, INC., SANTA BARBARA, CALIFORNIA
00007  *          ALL RIGHTS RESERVED.
00008  *
00009  *          THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND
00010  *          COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH
00011  *          THE INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE OR ANY
00012  *          OTHER COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE
00013  *          AVAILABLE TO ANY OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF THE
00014  *          SOFTWARE IS HEREBY TRANSFERRED.
00015  *
00016  *          THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT
00017  *          NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY CONDOR
00018  *          ENGINEERING.
00019  *
00020  *============================================================================*
00021  *
00022  * FUNCTION:    CAN api bit-level manipulation functions
00023  *
00024  * Author:      Christopher McKenzie
00025  * 
00026  * MAINTENANCE NOTES:
00027  * 
00028  *============================================================================*/
00029 #include"..\includes\defines.h"
00030 #include"..\includes\canapi.h"
00031 #include<stdlib.h>
00032 #include<stdio.h>
00033 #include<string.h>
00034 
00035 int _stdcall rightshifteverything(      unsigned char*from,
00036                                                                         int bitdistance,
00037                                                                         int bitsize)    //TESTTEST
00038 {       int ix,
00039                 bytesize=(bitsize>>3)+1,
00040                 bytestart,
00041                 bitoffset;
00042 
00043         unsigned char
00044                         *to=malloc(bytesize),
00045                         *chrfromstart,
00046                         *chrtostart,
00047                         tranbits;
00048         
00049         memset(to,0,bytesize);
00050         bytestart=bitdistance>>3;                               //bytes to shift
00051         bitoffset=bitdistance-(bytestart<<3);   //bits to shift
00052 
00053         //                     [XX]
00054         //          |     DATA :  |             AFTER   (RIGHT)
00055         //          [ new size ]
00056         //
00057         //              |     DATA     |                BEFORE
00058         //
00059         //      [ new size ]
00060         //   |  :  DATA     |                   AFTER   (LEFT)
00061         //   [XX]
00062         //
00063         //      First we handle the BYTE amount
00064         //
00065         bytesize-=bytestart;
00066         
00067         chrfromstart=from;
00068         chrtostart=to+bytestart;
00069 
00070         memcpy(chrtostart,chrfromstart,bytesize);
00071         //
00072         // Now we need to chain the bits
00073         //
00074         
00075         for(ix=bytesize;ix>0;ix--)      //to right shift we deal with bytes RTL
00076         {       //
00077                 // take the current tostart and bitshift it <bits> right
00078                 //
00079                 chrtostart[ix]>>=bitoffset;
00080                 //
00081                 // take the least significant <bits> of the previous byte
00082                 //
00083                 tranbits=chrtostart[ix-1]&maskLS[bitoffset];
00084                 //
00085                 // shift it over to be the MOST significant
00086                 //
00087                 tranbits<<=(8-bitoffset);
00088                 //
00089                 // OR it with the current byte
00090                 //
00091                 chrtostart[ix]|=tranbits;
00092         }
00093         //
00094         // Copy our result into from
00095         //
00096         memcpy(from,to,bytesize);
00097         //
00098         // Free our memory
00099         //
00100         free(to);
00101         return(1);
00102 }
00103 
00104 //
00105 // Copy some number of bytes of toset to a certain
00106 // bit offset of structure
00107 //
00108 int _stdcall setatbit(  unsigned char*structure,
00109                                 unsigned char*toset,
00110                                 int bitstart,
00111                                 int bitsize)
00112 {       int     bytesize=_GETBYTE(bitsize),
00113                 bitoffset=_GETBIT(bitsize),
00114                 bytestart=_GETBYTE(bitstart),
00115                 byteend=bytestart+bytesize;
00116 
00117         unsigned char*buffer;
00118         
00119         buffer=malloc(bytesize+1);
00120         memset(buffer,0,bytesize+1);
00121 
00122         memcpy(buffer,toset,bytesize);  //copy everything to an empty buffer
00123         rightshifteverything(buffer,bitoffset,bitsize);
00124         //
00125         // now that everything should be shifted we copy back, very carefully
00126         //
00127         //      The head and tail bytes are very *special* and need to be masked
00128         //  according to the offset.  These are bytestart and byteend.
00129         //
00130         // first we mask the first thing in "buffer" to 1's
00131         //
00132 
00133         buffer[0]&=maskMS[bitoffset];   //TESTTEST
00134         //
00135         // now we and it in the structure
00136         //
00137         structure[bytestart]&=buffer[0];
00138         //
00139         // do the bytes...
00140         //
00141         if( (byteend-1)-(bytestart+1) > 0)      //There are whole bytes
00142         {       memcpy(structure+bytestart+1,buffer+1,bytesize-2);
00143         }
00144         //
00145         // Now we take care of the last byte with the same trick as the first
00146         //
00147         buffer[bytesize]&=maskLS[8-bitoffset];  //TESTTEST
00148         structure[byteend]&=buffer[bytesize];
00149         //
00150         // And that's that.
00151         //
00152         return 1;
00153 }
00154 
00155 //
00156 // Copy some number of bytes of toset to a certain
00157 // bit offset of structure
00158 //
00159 int _stdcall getatbit(  unsigned char*structure,
00160                                 unsigned char*toset,
00161                                 int bitstart,
00162                                 int bitsize)    //BUGBUG
00163 {       int     bytesize=_GETBYTE(bitsize)+1,   //round up
00164                 bitoffset=_GETBIT(bitsize),
00165                 bytestart=_GETBYTE(bitstart),
00166                 byteend=bytestart+bytesize,
00167                 bitend=bitstart+bitsize;
00168 
00169         unsigned char*buffer;
00170         
00171         //
00172         // Round up, instead of down, by adding 1
00173         // Then add 1 for offset black magic.
00174         //
00175         buffer=malloc(bytesize+1);
00176         memset(buffer,0,bytesize+1);
00177 
00178         //
00179         // Now we have
00180         // [ BYTE ][ BYTE ]...[ BYTE ]
00181         //     ^^^^^^^^^^^^^^^^^^
00182 
00183         //
00184         // First we copy over all the bytes
00185         //
00186         memcpy(buffer,structure+bytestart,bytesize);
00187 
00188         //
00189         // Now we dump the last few bits of the last byte
00190         // by anding a mask with the first few bits
00191         //
00192         buffer[bytesize]&=maskMS[_GETBIT(bitend)];
00193 
00194         //
00195         // We are going to shift the last few bits of the 
00196         // first byte
00197         //
00198         rightshifteverything(buffer,8-bitoffset,bitsize);
00199 
00200         //
00201         // Now we can cut the remainder of the first byte
00202         // and everything is shifted already.
00203         //
00204         memcpy(toset,buffer+1,bytesize);        //dead serious, that easy
00205         return 1;
00206 }
00207 
00208 /*
00209 int _stdcall shifteverything(   unsigned char*from,
00210                                                 int direction,
00211                                                 int bitdistance,
00212                                                 int bitsize)
00213 {       int ix,
00214                 bytesize=(bitsize>>3)+1,
00215                 bytestart,
00216                 bitstart;
00217 
00218         unsigned char
00219                         *to=malloc(size),
00220                         *fromstart,
00221                         *tostart,
00222                         tranbits;
00223         
00224         memset(to,0,bytesize);
00225         bytestart=bitdistance>>3;                               //bytes to shift
00226         bitstart=bitdistance-(bytestart<<3);    //bits to shift
00227 
00228         //                     [XX]
00229         //          |     DATA :  |             AFTER   (RIGHT)
00230         //          [ new size ]
00231         //
00232         //              |     DATA     |                BEFORE
00233         //
00234         //      [ new size ]
00235         //   |  :  DATA     |                   AFTER   (LEFT)
00236         //   [XX]
00237         //
00238         //      First we handle the BYTE amount
00239         //
00240         bytesize-=bytestart;
00241         
00242         fromstart=from;
00243         tostart=to;
00244 
00245         if(direction==LEFT)
00246                 fromstart=from+bytes;
00247 
00248         else if(direction==RIGHT)
00249                 tostart=to+bytes;
00250 
00251         else
00252         {       printf("Bad direction");
00253                 return(0);
00254         }
00255 
00256         memcpy(tostart,fromstart,size);
00257         //
00258         // Now we need to chain the bits
00259         //
00260         if(direction==LEFT)     //we go left to right
00261         {       for(ix=0;ix<size;ix++)
00262                 {       //
00263                         // take the current tostart and bitshift it <bits> left
00264                         //
00265                         tostart[ix]<<=bits;
00266                         //
00267                         // take the most significant <bits> of the next byte
00268                         //
00269                         tranbits=tostart[ix+1]&maskMS[bits];
00270                         //
00271                         // Shift it over to be the LEAST significant
00272                         //
00273                         tranbits>>=(8-bits);
00274                         //
00275                         // OR it with the current byte
00276                         //
00277                         tostart[ix]|=tranbits;
00278                 }
00279         }
00280         if(direction==RIGHT)
00281         {       for(ix=size;ix>0;ix--)  //We go right to left
00282                 {       //
00283                         // take the current tostart and bitshift it <bits> right
00284                         //
00285                         tostart[ix]>>=bits;
00286                         //
00287                         // take the least significant <bits> of the previous byte
00288                         //
00289                         tranbits=tostart[ix-1]&maskLS[bits];
00290                         //
00291                         // shift it over to be the MOST significant
00292                         //
00293                         tranbits<<=(8-bits);
00294                         //
00295                         // OR it with the current byte
00296                         //
00297                         tostart[ix]|=tranbits;
00298                 }
00299         }
00300         //
00301         // Copy our result into from
00302         //
00303         memcpy(from,to,size);
00304         //
00305         // Free our memory
00306         //
00307         free(to);
00308         return(1);
00309 }
00310 
00311 */

Generated on Wed Feb 22 13:31:26 2006 for CANapi by  doxygen 1.4.4