serial.c

00001 /****************************************************************************
00002 
00003  \file      ctl/serial.c
00004  \ingroup   Patterns
00005  \brief     Serial support functions
00006  \author    David Mace
00007 
00008 Serial Handling
00009 
00010 Serial data is generally stored little-endian for this handling, to take 
00011 advantage of the native format of Intel architecture, which is the most 
00012 common type we'll find, and supports odd-aligned data accesses, which makes 
00013 serializing it a piece of cake.  On most big-endian hardware, there is no 
00014 savings possible, as odd data alignment will generate exceptions, so we 
00015 take advantage of the most common target with the most lucrative feature.
00016 
00017 Arrays of scalars and wide character strings are stored all lowest bytes as 
00018 an array, then each more significant byte as a seperate array.  This 
00019 generally helps the data compress better for many kinds of scalar data.
00020 
00021 define SERIAL_BIG_ENDIAN If you want big-endian data
00022 SERIAL_BIG_ENDIAN is the default.
00023 
00024 define SERIAL_LITTLE_ENDIAN  If you want little-endian data
00025 
00026 define SERIAL_NATIVE If your target platform doesn't mind reading/writing odd 
00027 addresses, and you want its native endian-ness.
00028 
00029 SERIAL_NATIVE is naturally the fastest for serial-intensive applications, but 
00030 only supportable under certain situations.
00031 
00032 For a Windows+Intel or Linux+Intel style computer, SERIAL_NATIVE is little-endian
00033 
00034 *****************************************************************************/
00035 #define SERIAL_C
00036 #include "ctl/ctldef.h"
00037 #include "ctl/dg/datagen.h"
00038 #include "ctl/algorithm.temp.h"
00039 #include "ctl/serial.h"
00040 
00041 /*
00042  * Default serial error handler: Log packet and throw an assertion
00043  */
00044 static void def_serial_exception( const struct ctl_serial* serial, const char* reason )
00045 {
00046     serial_log( serial, LOG_ERROR, 
00047         "ctl_serial: %s\n"
00048         "\tbegin:%p\n"
00049         "\tcurr:%p\n"
00050         "\tend:%p\n",
00051         reason,
00052         serial->begin,
00053         serial->curr,
00054         serial->end
00055         );
00056     assert( !isdebugging() );
00057     /* longjmp back to setjmp handler... */
00058 }
00059 
00060 ctl_serial_exception ctl_serial_except = def_serial_exception; 
00067 ctl_serial_exception ctl_serial_setexception( ctl_serial_exception except )
00068 {
00069     ctl_serial_exception ctl_serial_except_prev = ctl_serial_except;
00070     ctl_serial_except = NULL == except ? def_serial_exception : except;
00071     assertcodeptr(ctl_serial_except);
00072     return ctl_serial_except_prev;
00073 }
00074 
00083 void serial_log( const ctl_serial* serial, unsigned mask, const char* fmt, ... )
00084 {
00085     if( (mask & debug_getlogmask()) || 0 == mask )
00086     {
00087         ctl_serial dumpit = *serial;
00088         char printable[16];
00089         const uint8* pBuff;
00090         size_t size = serial->end - serial->begin;
00091         size_t curr = 0;
00092         size_t offAddress = 0;
00093         /* Attach whatever other diagnostic info */
00094         va_list args;
00095         va_start( args, fmt );
00096         debug_vlogalways( fmt, args );
00097         /* Clip dump down to a maximum size of dump, so we don't cripple ourselves reporting problems */
00098 #ifndef SERIAL_MAX_DUMP
00099 #define SERIAL_MAX_DUMP 80
00100 #endif
00101         if( size > SERIAL_MAX_DUMP )
00102         {
00103             dumpit.begin = (uint8*)max(dumpit.begin,dumpit.curr-(SERIAL_MAX_DUMP/2));
00104             dumpit.end = (uint8*)min(dumpit.end,dumpit.curr+(SERIAL_MAX_DUMP/2));
00105             offAddress = dumpit.begin - serial->begin;
00106             size = SERIAL_MAX_DUMP;
00107         }
00108         /* Do hex dump */
00109         pBuff = (const uint8*)dumpit.begin;
00110         while( pBuff < dumpit.end )
00111         {
00112             unsigned ch = *pBuff++;
00113             if( 0 == (curr & 0xf) )
00114             {
00115                 debug_logalways( "%08x:%c", curr+offAddress, pBuff == dumpit.curr-1 ? '>' : ' ' );
00116             }
00117             printable[curr&0xf] = isprint(ch) ? ch : '.';
00118             if( 0xf == (curr++ & 0xf) )
00119             {
00120                 debug_logalways( "%02x | %16.16s\n", ch, printable );
00121             }
00122             else
00123             {
00124                 debug_logalways( "%02x%c", ch, pBuff == dumpit.curr ? '>' : ' ' );
00125             }
00126         }
00127         /* Leftovers */
00128         if( 0 != (size & 0xf) )
00129         {
00130             for( curr = curr & 0xf; curr < 16; ++curr )
00131             {
00132                 debug_logalways( "-- " );
00133                 printable[curr] = ' ';
00134             }
00135             debug_logalways( "| %16.16s\n", printable );
00136         }
00137     }
00138 }
00139 
00148 void ctl_serial_copy( ctl_serial* dst, const ctl_serial* src )
00149 {
00150     assertobjptr(dst);
00151     assertobjconst(src);
00152     if( src->buff )
00153     {
00154         size_t size = ctl_serial_total( src );
00155         ctl_serial_alloc( dst, size );
00156         memcpy( dst->buff, src->begin, size );
00157         dst->curr = (uint8*)dst->begin + (src->curr-src->begin);
00158     }
00159     else
00160     {
00161         *dst = *src;
00162         dst->buff = NULL;
00163     }
00164 }
00165 
00171 void ctl_serial_deref( ctl_serial* serial )
00172 {
00173     assertobjptr(serial);
00174     if( NULL == serial->buff )
00175     {   /* Only operate if not already a reference */
00176         ctl_serial tmp = *serial;
00177         size_t size = ctl_serial_total( &tmp );
00178         ctl_serial_alloc( serial, size );
00179         memcpy( serial->buff, tmp.begin, size );
00180         serial->curr = (uint8*)serial->begin + (tmp.curr-tmp.begin);
00181     }
00182 }
00183 
00184 
00191 void ctl_serial_writesize( size_t size, ctl_serial* serial )
00192 {
00193     /* There SHOULD have been enough pre-allocated */
00194     uint16 wsize = (uint16)size;
00195     assertobjptr(serial);
00196     assert( size < 65536 );
00197     assert( serial->curr + ctl_serial_size_size_size( size ) <= serial->end );
00198     uint16_serial_write( &wsize, serial );
00199 }
00200 
00207 size_t ctl_serial_peeksize( const ctl_serial* serial )
00208 {
00209     uint16 wsize = 0;
00210     assertobjconst(serial);
00211     uint16_serial_peek( &wsize, serial );
00212     return wsize;
00213 }
00214 
00221 size_t ctl_serial_readsize( ctl_serial* serial )
00222 {
00223     uint16 wsize = 0;
00224     assertobjptr(serial);
00225     uint16_serial_read( &wsize, serial );
00226     if( serial->curr + wsize > serial->end )
00227     {
00228         ctl_serial_except( serial, "Bound check failure getting size" );
00229         return 0;
00230     }
00231     return wsize;
00232 }
00233 
00240 size_t ctl_serial_calc_size( const ctl_serial* serial )
00241 {
00242     assertobjconst(serial);
00243     return ctl_serial_size_size_size( ctl_serial_total( serial ) );
00244 }
00245 
00252 void ctl_serial_write_serial( ctl_serial* dst, const ctl_serial* src )
00253 {
00254     assertobjptr(dst);
00255     assertobjconst(src);
00256     {
00257         size_t total = ctl_serial_total( src );
00258         ctl_serial_writesize( total, dst );
00259         memcpy( dst->curr, src->begin, total );
00260         dst->curr += total;
00261     }
00262 }
00263 
00270 bool ctl_serial_read_serial( ctl_serial* dst, ctl_serial* src )
00271 {
00272     assertobjptr(dst);
00273     assertobjptr(src);
00274     {
00275         size_t total = ctl_serial_readsize( src );
00276         dst->begin = dst->curr = (uint8*)src->curr;
00277         dst->end = dst->begin + total;
00278         src->curr += total;
00279         return 0 != total;
00280     }
00281 }
00282 
00289 bool ctl_serial_peek_serial( ctl_serial* dst, const ctl_serial* src )
00290 {
00291     assertobjptr(dst);
00292     assertobjconst(src);
00293     {
00294         size_t total = ctl_serial_peeksize( src );
00295         dst->begin = dst->curr = (uint8*)src->curr + ctl_serial_size_size( total );
00296         dst->end = dst->begin + total;
00297         return 0 != total;
00298     }
00299 }
00300 
00301 
00305 size_t bool_serial_sizearray( const bool*  array, size_t count)
00306 {
00307     assertconst(array,count*sizeof(bool));
00308     return ctl_serial_size_size_size( count );
00309 }
00313 void bool_serial_writearray( const bool* array, size_t count, ctl_serial* serial )
00314 {
00315     size_t size = count;
00316     assertconst(array,count*sizeof(bool));
00317     assertobjptr(serial);
00318     ctl_serial_writesize( size, serial );
00319     assert( serial->curr + size <= serial->end );
00320     {
00321         pointer_foreach_const(bool,array,count, curr )
00322         {
00323             *serial->curr++ = (uint8)*curr;
00324         }
00325     }
00326 }
00330 void bool_serial_readarray( bool* array, size_t count, ctl_serial* serial )
00331 {
00332     size_t size;
00333     assertobjptr(serial);
00334     assertobjptr(array);
00335     size = ctl_serial_readsize( serial );
00336     if( size <= count )
00337     {
00338         pointer_foreach(bool,array,count, curr )
00339         {
00340             /* Probably should generate exception if these are not 0 or 1 */
00341             uint8 tmp = *serial->curr++;
00342             *curr = 0 != tmp;
00343         }
00344     }
00345     else
00346     {
00347         pointer_foreach(bool,array,size, curr )
00348         {
00349             /* Probably should generate exception if these are not 0 or 1 */
00350             uint8 tmp = *serial->curr++;
00351             *curr = 0 != tmp;
00352         }
00353         serial->curr += size-count;
00354     }
00355 }
00356 
00363 void uint8_serial_write( const uint8* pdata, ctl_serial* serial )
00364 {
00365     assertobjptr(serial);
00366     assertconst(pdata,sizeof(*pdata));
00367     assert( serial->curr < serial->end );
00368     *serial->curr++ = *pdata;
00369 }
00370 
00377 void uint8_serial_read( uint8* pdata, ctl_serial* serial )
00378 {
00379     assertobjptr(serial);
00380     assertptr(pdata,sizeof(*pdata));
00381     if( serial->curr < serial->end )
00382         *pdata = *serial->curr++;
00383     else
00384         ctl_serial_except( serial, "ctl_serial_read: Bound check failure" );
00385 }
00386 
00393 void uint8_serial_peek( uint8* pdata, const ctl_serial* serial )
00394 {
00395     assertobjconst(serial);
00396     assertptr(pdata,sizeof(*pdata));
00397     if( serial->curr < serial->end )
00398         *pdata = *serial->curr;
00399     else
00400         ctl_serial_except( serial, "ctl_serial_read: Bound check failure" );
00401 }
00402 
00410 size_t uint8_serial_sizearray( const uint8* array, size_t count)
00411 {
00412     size_t size = count;
00413     assertconst(array,count*sizeof(array));
00414     return ctl_serial_size_size_size( size );
00415 }
00423 void uint8_serial_writearray( const uint8*  array, size_t count, ctl_serial* serial )
00424 {
00425     size_t size = count;
00426     assertobjptr(serial);
00427     assertconst(array,count*sizeof(array));
00428     ctl_serial_writesize( size, serial );
00429     assert( serial->curr + size <= serial->end );
00430     memcpy( serial->curr, array, size );
00431     serial->curr += size;
00432 }
00433 
00441 void uint8_serial_readarray( uint8* array, size_t count, ctl_serial* serial )
00442 {
00443     size_t size = ctl_serial_readsize( serial );
00444     assertobjptr(serial);
00445     assertptr(array,count*sizeof(array));
00446     if( size > count )
00447         ctl_serial_except( serial, "serial_readarray: Too big" );
00448     count = min(count,size);
00449     memcpy( array, serial->curr, count );
00450     serial->curr += size;
00451 }
00452 
00459 void uint16_serial_write(const uint16* pdata, ctl_serial* serial )
00460 {
00461     assertobjptr(serial);
00462     assertconst(pdata,sizeof(*pdata));
00463     assert( serial->curr+2 <= serial->end );
00464 #if defined(SERIAL_LITTLE_ENDIAN)
00465     {
00466         uint8* curr = serial->curr;
00467         *curr++ = (uint8)(*pdata);
00468         *curr++ = (uint8)(*pdata>>8);
00469         serial->curr = curr;
00470     }
00471 #elif defined(SERIAL_BIG_ENDIAN)
00472     {
00473         uint8* curr = serial->curr+1;
00474         *curr-- = (uint8)(*pdata);
00475         *curr = (uint8)(*pdata>>8);
00476         serial->curr += 2;
00477     }
00478 #elif defined(SERIAL_NATIVE)
00479     *((uint16*)serial->curr) = *pdata;
00480     serial->curr += 2;
00481 #endif
00482 }
00483 
00490 void uint16_serial_read(uint16* pdata, ctl_serial* serial )
00491 {
00492     assertobjptr(serial);
00493     assertptr(pdata,sizeof(*pdata));
00494     if( serial->curr + 2 <= serial->end )
00495     {
00496 #if defined(SERIAL_LITTLE_ENDIAN)
00497         const uint8* curr = serial->curr + 1;
00498         *pdata = (uint16)*curr--;
00499         *pdata <<= 8;
00500         *pdata |= (uint16)*curr;
00501         serial->curr += 2;
00502 #elif defined(SERIAL_BIG_ENDIAN)
00503         const uint8* curr = serial->curr;
00504         *pdata = (uint16)*curr++;
00505         *pdata <<= 8;
00506         *pdata |= (uint16)*curr++;
00507         serial->curr = (uint8*)curr;
00508 #elif defined(SERIAL_NATIVE)
00509         *pdata = *((uint16*)serial->curr);
00510         serial->curr += 2;
00511 #endif
00512     }
00513     else
00514     {
00515         ctl_serial_except( serial, "ctl_serial_read: Bound check failure" );
00516     }
00517 }
00518 
00525 void uint16_serial_peek( uint16* pdata, const ctl_serial* serial )
00526 {
00527     assertobjconst(serial);
00528     assertptr(pdata,sizeof(*pdata));
00529     {
00530         ctl_serial temp = *serial;
00531         uint16_serial_read( pdata, &temp );
00532     }
00533 }
00534 
00542 size_t uint16_serial_sizearray(const uint16* array, size_t count)
00543 {
00544     size_t size = count * sizeof(uint16);
00545     assertconst(array,count*sizeof(array));
00546     return ctl_serial_size_size_size( size );
00547 }
00548 
00556 void uint16_serial_writearray(const uint16* array, size_t count, ctl_serial* serial )
00557 {
00558     size_t size = count<<1;
00559     assertobjptr(serial);
00560     assertconst(array,count*sizeof(array));
00561     ctl_serial_writesize( size, serial );
00562     assert( serial->curr + size <= serial->end );
00563     {
00564         pointer_foreach_const(uint16,array,count, curr )
00565             uint16_serial_write(curr,serial);
00566     }
00567 }
00568 
00576 void uint16_serial_readarray(uint16* array, size_t count, ctl_serial* serial )
00577 {
00578     size_t size;
00579     size_t serialCount;
00580     assertobjptr(serial);
00581     assertptr(array,count*sizeof(array));
00582     size = ctl_serial_readsize( serial );
00583     serialCount = size>>1;
00584     if( size & 1 )
00585         ctl_serial_except( serial, "uint16_serial_readarray: Odd size" );
00586     if( serialCount > count )
00587         serialCount = count;
00588     {
00589         pointer_foreach(uint16,array,serialCount, curr )
00590             uint16_serial_read(curr,serial);
00591     }
00592     if( serialCount < count )
00593     {
00594         size_t leftover = size - (count<<1);
00595         serial->curr += size - (count<<1);
00596         memset( array + count, 0, leftover );
00597     }
00598     else
00599     {
00600         serial->curr += size - (count<<1);
00601     }
00602 }
00603 
00610 void uint32_serial_write(const uint32* pdata, ctl_serial* serial )
00611 {
00612     assertobjptr(serial);
00613     assertconst(pdata,sizeof(*pdata));
00614     assert( serial->curr+4 <= serial->end );
00615 #if defined(SERIAL_LITTLE_ENDIAN)
00616     {
00617         register uint8* curr = serial->curr;
00618         register uint32 val = *pdata;
00619         *curr++ = (uint8)(val);
00620         val >>= 8;
00621         *curr++ = (uint8)(val);
00622         val >>= 8;
00623         *curr++ = (uint8)(val);
00624         val >>= 8;
00625         *curr++ = (uint8)(val);
00626         serial->curr = curr;
00627     }
00628 #elif defined(SERIAL_BIG_ENDIAN)
00629     {
00630         register uint8* curr = serial->curr+3;
00631         register uint32 val = *pdata;
00632         *curr-- = (uint8)(val);
00633         val >>= 8;
00634         *curr-- = (uint8)(val);
00635         val >>= 8;
00636         *curr-- = (uint8)(val);
00637         val >>= 8;
00638         *curr = (uint8)(val);
00639         serial->curr += 4;
00640     }
00641 #elif defined(SERIAL_NATIVE)
00642     *((uint32*)serial->curr) = *pdata;
00643     serial->curr += 4;
00644 #endif
00645 }
00646 
00653 void uint32_serial_read(uint32* pdata, ctl_serial* serial )
00654 {
00655     assertobjptr(serial);
00656     assertptr(pdata,sizeof(*pdata));
00657     if( serial->curr + 4 <= serial->end )
00658     {
00659 #if defined(SERIAL_LITTLE_ENDIAN)
00660         register const uint8* curr = serial->curr + 3;
00661         register uint32 tmp = (uint32)*curr--;
00662         tmp <<= 8;
00663         tmp |= (uint32)*curr--;
00664         tmp <<= 8;
00665         tmp |= (uint32)*curr--;
00666         tmp <<= 8;
00667         tmp |= (uint32)*curr;
00668         *pdata = tmp;
00669         serial->curr += 4;
00670 #elif defined(SERIAL_BIG_ENDIAN)
00671         register const uint8* curr = serial->curr;
00672         register uint32 tmp = (uint32)*curr++;
00673         tmp <<= 8;
00674         tmp |= (uint32)*curr++;
00675         tmp <<= 8;
00676         tmp |= (uint32)*curr++;
00677         tmp <<= 8;
00678         tmp |= (uint32)*curr++;
00679         *pdata = tmp;
00680         serial->curr = (uint8*)curr;
00681 #elif defined(SERIAL_NATIVE)
00682         *pdata = *((uint32*)serial->curr);
00683         serial->curr += 4;
00684 #endif
00685     }
00686     else
00687     {
00688         ctl_serial_except( serial, "ctl_serial_read: Bound check failure" );
00689     }
00690 }
00691 
00698 void uint32_serial_peek(uint32* pdata, ctl_serial* serial )
00699 {
00700     assertobjptr(serial);
00701     assertptr(pdata,sizeof(*pdata));
00702     {
00703         ctl_serial temp = *serial;
00704         uint32_serial_read( pdata, &temp );
00705     }
00706 }
00707 
00708 
00716 size_t uint32_serial_sizearray(const uint32* array, size_t count)
00717 {
00718     size_t size = count * sizeof(uint32);
00719     assertconst(array,count*sizeof(array));
00720     return ctl_serial_size_size_size( size );
00721 }
00722 
00730 void uint32_serial_writearray(const uint32* array, size_t count, ctl_serial* serial )
00731 {
00732     size_t size = count<<2;
00733     assertobjptr(serial);
00734     assertconst(array,count*sizeof(array));
00735     ctl_serial_writesize( size, serial );
00736     assert( serial->curr + size <= serial->end );
00737     {
00738         pointer_foreach_const(uint32,array,count, curr )
00739             uint32_serial_write(curr,serial);
00740     }
00741 }
00742 
00750 void uint32_serial_readarray(uint32* array, size_t count, ctl_serial* serial )
00751 {
00752     size_t size;
00753     size_t serialCount;
00754     assertobjptr(serial);
00755     assertptr(array,count*sizeof(array));
00756     size = ctl_serial_readsize( serial );
00757     serialCount = size>>2;
00758     if( size & 3 )
00759         ctl_serial_except( serial, "uint32_serial_readarray: Odd size" );
00760     if( serialCount > count )
00761         serialCount = count;
00762     {
00763         pointer_foreach(uint32,array,serialCount, curr )
00764             uint32_serial_read(curr,serial);
00765     }
00766     if( serialCount < count )
00767     {
00768         size_t leftover = size - (count<<2);
00769         serial->curr += size - (count<<2);
00770         memset( array + count, 0, leftover );
00771     }
00772     else
00773     {
00774         serial->curr += size - (count<<2);
00775     }
00776 }
00777 
00784 void uint64_serial_write(const uint64* pdata, ctl_serial* serial )
00785 {
00786     assertobjptr(serial);
00787     assertconst(pdata,sizeof(*pdata));
00788     assert( serial->curr+8 <= serial->end );
00789 #if defined(SERIAL_LITTLE_ENDIAN)
00790     {
00791         register uint8* curr = serial->curr;
00792         register uint64 val = *pdata;
00793         *curr++ = (uint8)(val);
00794         val >>= 8;
00795         *curr++ = (uint8)(val);
00796         val >>= 8;
00797         *curr++ = (uint8)(val);
00798         val >>= 8;
00799         *curr++ = (uint8)(val);
00800         val >>= 8;
00801         *curr++ = (uint8)(val);
00802         val >>= 8;
00803         *curr++ = (uint8)(val);
00804         val >>= 8;
00805         *curr++ = (uint8)(val);
00806         val >>= 8;
00807         *curr++ = (uint8)(val);
00808         serial->curr = curr;
00809     }
00810 #elif defined(SERIAL_BIG_ENDIAN)
00811     {
00812         register uint8* curr = serial->curr+7;
00813         register uint64 val = *pdata;
00814         *curr-- = (uint8)(val);
00815         val >>= 8;
00816         *curr-- = (uint8)(val);
00817         val >>= 8;
00818         *curr-- = (uint8)(val);
00819         val >>= 8;
00820         *curr-- = (uint8)(val);
00821         val >>= 8;
00822         *curr-- = (uint8)(val);
00823         val >>= 8;
00824         *curr-- = (uint8)(val);
00825         val >>= 8;
00826         *curr-- = (uint8)(val);
00827         val >>= 8;
00828         *curr = (uint8)(val);
00829         serial->curr += 8;
00830     }
00831 #elif defined(SERIAL_NATIVE)
00832     *((uint64*)serial->curr) = *pdata;
00833     serial->curr += 8;
00834 #endif
00835 }
00836 
00843 void uint64_serial_read(uint64* pdata, ctl_serial* serial )
00844 {
00845     assertobjptr(serial);
00846     assertptr(pdata,sizeof(*pdata));
00847     if( serial->curr + 8 <= serial->end )
00848     {
00849 #if defined(SERIAL_LITTLE_ENDIAN)
00850         register const uint8* curr = serial->curr + 7;
00851         register uint64 tmp = (uint64)*curr--;
00852         tmp <<= 8;
00853         tmp |= (uint64)*curr--;
00854         tmp <<= 8;
00855         tmp |= (uint64)*curr--;
00856         tmp <<= 8;
00857         tmp |= (uint64)*curr--;
00858         tmp <<= 8;
00859         tmp |= (uint64)*curr--;
00860         tmp <<= 8;
00861         tmp |= (uint64)*curr--;
00862         tmp <<= 8;
00863         tmp |= (uint64)*curr--;
00864         tmp <<= 8;
00865         tmp |= (uint64)*curr;
00866         *pdata = tmp;
00867         serial->curr += 8;
00868 #elif defined(SERIAL_BIG_ENDIAN)
00869         register const uint8* curr = serial->curr;
00870         register uint64 tmp = (uint64)*curr++;
00871         tmp <<= 8;
00872         tmp |= (uint64)*curr++;
00873         tmp <<= 8;
00874         tmp |= (uint64)*curr++;
00875         tmp <<= 8;
00876         tmp |= (uint64)*curr++;
00877         tmp <<= 8;
00878         tmp |= (uint64)*curr++;
00879         tmp <<= 8;
00880         tmp |= (uint64)*curr++;
00881         tmp <<= 8;
00882         tmp |= (uint64)*curr++;
00883         tmp <<= 8;
00884         tmp |= (uint64)*curr++;
00885         *pdata = tmp;
00886         serial->curr = (uint8*)curr;
00887 #elif defined(SERIAL_NATIVE)
00888         *pdata = *((uint64*)serial->curr);
00889         serial->curr += 8;
00890 #endif
00891     }
00892     else
00893     {
00894         ctl_serial_except( serial, "ctl_serial_read: Bound check failure" );
00895     }
00896 }
00897 
00904 void uint64_serial_peek(uint64* pdata, ctl_serial* serial )
00905 {
00906     assertobjptr(serial);
00907     assertptr(pdata,sizeof(*pdata));
00908     {
00909         ctl_serial temp = *serial;
00910         uint64_serial_read( pdata, &temp );
00911     }
00912 }
00913 
00921 size_t uint64_serial_sizearray(const uint64* array, size_t count)
00922 {
00923     size_t size = count * sizeof(uint64);
00924     assertconst(array,count*sizeof(array));
00925     return ctl_serial_size_size_size( size );
00926 }
00927 
00935 void uint64_serial_writearray(const uint64* array, size_t count, ctl_serial* serial )
00936 {
00937     size_t size = count << 3;
00938     assertobjptr(serial);
00939     assertconst(array,count*sizeof(array));
00940     ctl_serial_writesize( size, serial );
00941     assert( serial->curr + size <= serial->end );
00942     {
00943         pointer_foreach_const(uint64,array,count, curr )
00944             uint64_serial_write(curr,serial);
00945     }
00946 }
00947 
00948 
00956 void uint64_serial_readarray(uint64* array, size_t count, ctl_serial* serial )
00957 {
00958     size_t size;
00959     size_t serialCount;
00960     assertobjptr(serial);
00961     assertptr(array,count*sizeof(array));
00962     size = ctl_serial_readsize( serial );
00963     serialCount = size>>3;
00964     if( size & 7 )
00965         ctl_serial_except( serial, "uint64_serial_readarray: Odd size" );
00966     if( serialCount > count )
00967         serialCount = count;
00968     {
00969         pointer_foreach(uint64,array,serialCount, curr )
00970             uint64_serial_read(curr,serial);
00971     }
00972     if( serialCount < count )
00973     {
00974         size_t leftover = size - (count<<3);
00975         serial->curr += size - (count<<3);
00976         memset( array + count, 0, leftover );
00977     }
00978     else
00979     {
00980         serial->curr += size - (count<<3);
00981     }
00982 }
00983 
00991 size_t char_serial_size_string( const char* sz, size_t szmax )
00992 {
00993     assertconst(sz,1);
00994     {
00995         size_t len = cstrnlen(char)(sz,szmax);
00996         return ctl_serial_size_size_size( len );
00997     }
00998 }
00999 
01007 size_t wchar_t_serial_size_string( const wchar_t* sz, size_t szmax )
01008 {
01009     assertconst(sz,sizeof(wchar_t));
01010     {
01011         size_t len = cstrnlen(wchar_t)(sz,szmax) * 2;
01012         return ctl_serial_size_size_size( len );
01013     }
01014 }
01015 
01023 void char_serial_write_string( const char* sz, size_t szmax, ctl_serial* serial )
01024 {
01025     size_t len;
01026     assertconst(sz,sizeof(char));
01027     assertobjptr(serial);
01028     len = cstrnlen(char)(sz,szmax);
01029     ctl_serial_writesize( (uint32)len, serial );
01030     assert( serial->curr + len <= serial->end );
01031     memcpy( serial->curr, sz, len );
01032     serial->curr += len;
01033 }
01034 
01042 void wchar_t_serial_write_string( const wchar_t* sz, size_t szmax, ctl_serial* serial )
01043 {
01044     size_t count;
01045     assertconst(sz,sizeof(wchar_t));
01046     assertobjptr(serial);
01047     count = cstrnlen(wchar_t)(sz,szmax);
01048     ctl_serial_writesize( count*2, serial );
01049     assert( serial->curr + (count*2) <= serial->end );
01050     {
01051         uint16 ch;
01052         pointer_foreach_const(wchar_t,sz,count, curr )
01053         {
01054             ch = *curr;
01055             uint16_serial_write( &ch, serial );
01056         }
01057     }
01058 }
01059 
01067 void char_serial_read_string( char* sz, size_t szmax, ctl_serial* serial )
01068 {
01069     size_t len;
01070     size_t toget;
01071     assertconst(sz,sizeof(char));
01072     assertobjptr(serial);
01073     len = ctl_serial_readsize( serial );
01074     toget = min(len,szmax);
01075     memcpy(sz,serial->curr,toget);
01076     if( toget < szmax )
01077         sz[toget] = 0;
01078     serial->curr += len;
01079 }
01080 
01088 void wchar_t_serial_read_string( wchar_t* sz, size_t count, ctl_serial* serial )
01089 {
01090     size_t size;
01091     size_t readcount;
01092     assertconst(sz,sizeof(wchar_t));
01093     assertobjptr(serial);
01094     size = ctl_serial_readsize( serial );
01095     if( size & 1 )
01096         ctl_serial_except( serial, "ctl_serial_read_string: Odd size" );
01097     size>>=1;
01098     readcount = min(count,size);
01099     {
01100         pointer_foreach(wchar_t, sz, readcount, curr )
01101         {
01102             uint16 ch = 0;
01103             uint16_serial_read( &ch, serial );
01104             *curr = (wchar_t)ch;
01105         }
01106     }
01107     if( readcount < count )
01108         sz[readcount] = 0;
01109     serial->curr += (size-readcount)<<1;
01110 }
01111 
01118 void char_serial_read_gstring( ctl_gstring(char)* str, ctl_serial* serial )
01119 {
01120     size_t msize;
01121     assertobjptr(str);
01122     assertobjptr(serial);
01123     msize = chslength(char,ctl_serial_peeksize( serial ));
01124     ctl_gstring_resize(char, str, msize );
01125     ppConcat(char,_serial_read_string)( str->begin, msize, serial );
01126 }
01127 
01134 void wchar_t_serial_read_gstring( ctl_gstring(wchar_t)* str, ctl_serial* serial )
01135 {
01136     size_t msize;
01137     assertobjptr(str);
01138     assertobjptr(serial);
01139     msize = chslength(wchar_t,ctl_serial_peeksize( serial ));
01140     ctl_gstring_resize(wchar_t, str, msize );
01141     ppConcat(wchar_t,_serial_read_string)( str->begin, msize, serial );
01142 }
01143 
01150 void char_serial_read_fstring( ctl_gstring(char)* str, ctl_serial* serial )
01151 {
01152     size_t msize;
01153     size_t maxsize;
01154     assertobjptr(str);
01155     assertobjptr(serial);
01156     msize = chslength(char,ctl_serial_peeksize( serial ));
01157     maxsize = ctl_fstring_maxsize(char,str);
01158     if( msize > maxsize )
01159         msize = maxsize;
01160     ppConcat(char,_serial_read_string)( str->begin, msize, serial );
01161 }
01168 void wchar_t_serial_read_fstring( ctl_gstring(wchar_t)* str, ctl_serial* serial )
01169 {
01170     size_t msize;
01171     size_t maxsize;
01172     assertobjptr(str);
01173     assertobjptr(serial);
01174     msize = chslength(wchar_t,ctl_serial_peeksize( serial ));
01175     maxsize = ctl_fstring_maxsize(char,str);
01176     if( msize > maxsize )
01177         msize = maxsize;
01178     ppConcat(wchar_t,_serial_read_string)( str->begin, msize, serial );
01179 }
01180 
01187 void char_serial_peek_sconst( ctl_sconst( char )* str, ctl_serial* serial )
01188 {
01189     size_t size;
01190     const char* pStr;
01191     assertobjptr(str);
01192     assertobjptr(serial);
01193     size = ctl_serial_peeksize( serial );
01194     pStr = (const char*)serial->curr + ctl_serial_size_size( size );
01195     ctl_sconst_init_pointers(char, str, pStr, pStr + size );
01196 }
01203 void wchar_t_serial_peek_sconst( ctl_sconst( wchar_t )* str, ctl_serial* serial )
01204 {
01205     size_t size;
01206     const uint8* pStr;
01207     assertobjptr(str);
01208     assertobjptr(serial);
01209     size = ctl_serial_peeksize( serial );
01210     pStr = serial->curr + ctl_serial_size_size( size );
01211     if( size & 1 )
01212         ctl_serial_except( serial, "ctl_serial_peek_string: Odd size" );
01213     size>>=1;
01214     ctl_sconst_init_pointers(wchar_t, str, (wchar_t*)pStr, (wchar_t*)pStr + size );
01215 }
01222 void char_serial_read_sconst( ctl_sconst( char )* str, ctl_serial* serial )
01223 {
01224     size_t size;
01225     const char* pStr;
01226     assertobjptr(str);
01227     assertobjptr(serial);
01228     size = ctl_serial_readsize( serial );
01229     pStr = (const char*)serial->curr;
01230     ctl_sconst_init_pointers(char, str, pStr, pStr + size );
01231     serial->curr += size;
01232 }
01239 void wchar_t_serial_read_sconst( ctl_sconst( wchar_t )* str, ctl_serial* serial )
01240 {
01241     size_t size;
01242     const uint8* pStr;
01243     assertobjptr(str);
01244     assertobjptr(serial);
01245     size = ctl_serial_readsize( serial );
01246     pStr = serial->curr;
01247     if( size & 1 )
01248         ctl_serial_except( serial, "ctl_serial_read_string: Odd size" );
01249     size>>=1;
01250     ctl_sconst_init_pointers(wchar_t, str, (wchar_t*)pStr, (wchar_t*)pStr + size );
01251     serial->curr += size;
01252 }

Generated on Fri Jan 2 15:28:34 2009 for Squat by  doxygen 1.5.6