00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <stdio.h>
00036 #include "ctl/dg/datagen.h"
00037 #include "ctl/algorithm.temp.h"
00038
00046 size_t ctl_record_head_size( const char* label, const char* type )
00047 {
00048 assertconst(label,1);
00049 assertconst(type,1);
00050 return
00051 sizeof(uint32) +
00052 sizeof(uint16) +
00053 cstrlen(char)( label ) + 1 +
00054 cstrlen(char)( type ) + 1;
00055 }
00056
00065 size_t ctl_record_objarray_head_size( const char* label, const char* type, const char* mbrtype )
00066 {
00067 assertconst(label,1);
00068 assertconst(type,1);
00069 assertconst(mbrtype,1);
00070 return
00071 sizeof(uint32) +
00072 sizeof(uint16) +
00073 cstrlen(char)( label ) + 1 +
00074 cstrlen(char)( type ) + 1 +
00075 cstrlen(char)( mbrtype ) + 1 +
00076 sizeof(uint32);
00077 }
00078
00085 bool ctl_record_valid( const ctl_serial* serial )
00086 {
00087 uint32 size;
00088 uint16 headersize;
00089 size_t labellen;
00090 size_t typelen;
00091 ctl_serial parse;
00092 assertobjconst(serial);
00093 parse = *serial;
00094
00095 if( serial->end - serial->curr < 10 )
00096 return false;
00097 uint32_serial_read(&size, &parse );
00098
00099 if( serial->curr + size > serial->end )
00100 return false;
00101 uint16_serial_read(&headersize, &parse );
00102
00103 if( serial->curr + headersize > serial->end )
00104 return false;
00105
00106 if( headersize > size )
00107 return false;
00108 labellen = cstrnlen(char)((char*)parse.curr,headersize-6);
00109
00110 if( labellen >= (size_t)(headersize-6) )
00111 return false;
00112 parse.curr += labellen;
00113
00114 if( *parse.curr )
00115 return false;
00116 parse.curr++;
00117 typelen = cstrnlen(char)((char*)parse.curr,headersize-(6+labellen));
00118 parse.curr += labellen;
00119
00120 if( *parse.curr )
00121 return false;
00122 parse.curr++;
00123
00124 if( 6 + labellen + 1 + typelen + 1 != headersize )
00125 return false;
00126
00127
00128 return true;
00129 }
00130
00137 bool ctl_record_next( ctl_serial* serial )
00138 {
00139 uint8* curr;
00140 uint32 offset;
00141 assertobjptr(serial);
00142 curr = serial->curr;
00143 uint32_serial_read(&offset, serial );
00144 if( curr + offset > serial->end )
00145 ctl_serial_except( serial, "ctl_record_next: Bad offset" );
00146 serial->curr = curr + offset;
00147 return serial->curr < serial->end;
00148 }
00149
00157 bool ctl_record_find( ctl_serial* serial, const char* label )
00158 {
00159 ctl_serial search;
00160 assertobjptr(serial);
00161 search = *serial;
00162 do
00163 {
00164 const char *szcurr = ctl_record_label( &search );
00165 if( !cstrcmp(char)( label, szcurr ) )
00166 {
00167 serial->curr = search.curr;
00168 return true;
00169 }
00170 }
00171 while( ctl_record_next( &search ) );
00172 return false;
00173 }
00174
00182 bool ctl_record_find_next( ctl_serial* serial, const char* label )
00183 {
00184 ctl_serial search;
00185 assertobjptr(serial);
00186 search = *serial;
00187 while( ctl_record_next( &search ) )
00188 {
00189 if( !cstrcmp(char)( label, ctl_record_label( &search ) ) )
00190 {
00191 serial->curr = search.curr;
00192 return true;
00193 }
00194 }
00195 return false;
00196 }
00197
00204 size_t ctl_record_getdata( ctl_serial* serial )
00205 {
00206 uint8* curr;
00207 uint32 offset;
00208 uint16 dataoffset;
00209 assertobjptr(serial);
00210 curr = serial->curr;
00211 uint32_serial_read(&offset, serial );
00212 uint16_serial_read(&dataoffset, serial );
00213 if( dataoffset > offset )
00214 ctl_serial_except( serial, "ctl_record_getdata: Bad offset" );
00215 if( curr + offset > serial->end )
00216 ctl_serial_except( serial, "ctl_record_getdata: Offset exceeds serial data" );
00217 serial->end = curr + offset;
00218 serial->curr = curr + dataoffset;
00219 return offset - dataoffset;
00220 }
00221
00230 size_t ctl_record_container_validatedata( ctl_serial* serial, const char* type, const char* mbrtype )
00231 {
00232 assertobjptr(serial);
00233 assertconst(type,1);
00234 assertconst(mbrtype,1);
00235 if( type && !ctl_record_type_is( type, serial ) )
00236 ctl_serial_except( serial, "ctl_record_container_validatedata: Mismatched container type" );
00237 if( mbrtype && !ctl_record_contained_type_is( mbrtype, serial ) )
00238 ctl_serial_except( serial, "ctl_record_container_validatedata: Mismatched content type" );
00239 {
00240 uint8* curr = serial->curr;
00241 uint32 offset;
00242 uint16 dataoffset;
00243 uint32 count;
00244 uint32_serial_read(&offset, serial );
00245 uint16_serial_read(&dataoffset, serial );
00246 if( dataoffset > offset )
00247 ctl_serial_except( serial, "ctl_record_container_validatedata: Bad offset" );
00248 if( curr + offset > serial->end )
00249 ctl_serial_except( serial, "ctl_record_container_validatedata: Offset exceeds serial data" );
00250 serial->end = curr + offset;
00251 serial->curr = curr + dataoffset - 4;
00252 uint32_serial_read(&count, serial );
00253 return count;
00254 }
00255 }
00256
00257
00264 const uint8* ctl_record_end( const ctl_serial* serial )
00265 {
00266 uint32 offset;
00267 ctl_serial tmp;
00268 assertobjconst(serial);
00269 tmp = *serial;
00270 uint32_serial_read(&offset, &tmp );
00271 if( serial->curr + offset > serial->end )
00272 ctl_serial_except( serial, "ctl_record_next: Bad offset" );
00273 return serial->curr + offset;;
00274 }
00275
00283 bool ctl_record_is( const char* label, const ctl_serial* serial )
00284 {
00285 assertconst(label,1);
00286 assertobjconst(serial);
00287 return !cstrcmp(char)( label, ctl_record_label( serial ) );
00288 }
00289
00290
00297 const char* ctl_record_label( const ctl_serial* serial )
00298 {
00299 assertobjconst(serial);
00300 if( serial->curr + 7 > serial->end )
00301 ctl_serial_except( serial, "ctl_record_label: Truncated" );
00302 return (const char*)(serial->curr + 6);
00303 }
00304
00311 const char* ctl_record_type( const ctl_serial* serial )
00312 {
00313 const char* label;
00314 assertobjconst(serial);
00315 label = ctl_record_label( serial );
00316 label += cstrnlen(char)(label,ctl_serial_remain(serial))+1;
00317 if( (uint8*)label >= serial->end )
00318 ctl_serial_except( serial, "ctl_record_type: Truncated" );
00319 return label;
00320 }
00321
00329 bool ctl_record_type_is( const char* label, const ctl_serial* serial )
00330 {
00331 assertconst(label,1);
00332 assertobjconst(serial);
00333 return !cstrcmp(char)( label, ctl_record_type( serial ) );
00334 }
00335
00342 const char* ctl_record_contained_type( const ctl_serial* serial )
00343 {
00344 const char* type;
00345 assertobjconst(serial);
00346 type = ctl_record_type( serial );
00347 type += cstrnlen(char)(type,ctl_serial_remain(serial))+1;
00348 if( (uint8*)type >= serial->end )
00349 ctl_serial_except( serial, "ctl_record_contained_type: Truncated" );
00350 return type;
00351 }
00352
00360 bool ctl_record_contained_type_is( const char* label, const ctl_serial* serial )
00361 {
00362 assertconst(label,1);
00363 assertobjconst(serial);
00364 return !cstrcmp(char)(label,ctl_record_contained_type( serial ) );
00365 }
00366
00373 size_t ctl_record_count( const ctl_serial* serial )
00374 {
00375 ctl_serial pserial;
00376 uint16 dataoffset;
00377 uint32 count;
00378 assertobjconst(serial);
00379 pserial = *serial;
00380 pserial.curr += 4;
00381 uint16_serial_read(&dataoffset, &pserial );
00382 pserial.curr = serial->curr + dataoffset - 4;
00383 uint32_serial_read(&count, &pserial );
00384 return count;
00385 }
00386
00396 uint8* ctl_record_write_begin( const char* type, size_t size, ctl_serial* serial, const char* label )
00397 {
00398 assertobjptr(serial);
00399 assertconst(type,1);
00400 assertconst(label,1);
00401 {
00402 uint8* ret = serial->curr;
00403 size_t lenLabel = cstrlen(char)(label)+1;
00404 size_t lenType = cstrlen(char)(type)+1;
00405 uint16 offData = (uint16)(lenLabel + lenType + 6);
00406 uint32 reserve = (uint32)size + offData;
00407
00408 assert( serial->curr + offData + size <= serial->end );
00409 uint32_serial_write(&reserve, serial );
00410 uint16_serial_write(&offData, serial );
00411 memcpy(serial->curr, label, lenLabel);
00412 serial->curr += lenLabel;
00413 memcpy(serial->curr, type, lenType);
00414 serial->curr += lenType;
00415 return ret;
00416 }
00417 }
00418
00419
00431 uint8* ctl_record_write_container_begin( const char* containertype, const char* contenttype, size_t size, size_t count, ctl_serial* serial, const char* label )
00432 {
00433 assertobjptr(serial);
00434 assertconst(containertype,1);
00435 assertconst(contenttype,1);
00436 assertconst(label,1);
00437 {
00438 uint8* ret = serial->curr;
00439 size_t lenLabel = cstrlen(char)(label)+1;
00440 size_t lenType = cstrlen(char)(containertype)+1;
00441 size_t lenContent = cstrlen(char)(contenttype)+1;
00442 uint16 offData = (uint16)(lenLabel + lenType + lenContent + 10);
00443 uint32 reserve = (uint32)size + offData;
00444 uint32 mbrcount = (uint32)count;
00445
00446 assert( serial->curr + offData + size <= serial->end );
00447 uint32_serial_write(&reserve, serial );
00448 uint16_serial_write(&offData, serial );
00449 memcpy(serial->curr, label, lenLabel);
00450 serial->curr += lenLabel;
00451 memcpy(serial->curr, containertype, lenType);
00452 serial->curr += lenType;
00453 memcpy(serial->curr, contenttype, lenContent);
00454 serial->curr += lenContent;
00455 uint32_serial_write(&mbrcount, serial );
00456 return ret;
00457 }
00458 }
00459
00466 void ctl_record_write_end( uint8* begret, ctl_serial* serial )
00467 {
00468 assertobjptr(serial);
00469 assertptr(begret,1);
00470 {
00471 uint8* tmp = serial->curr;
00472 uint32 size = (uint32)(serial->curr - begret);
00473 serial->curr = begret;
00474 uint32_serial_write( &size, serial );
00475 serial->curr = tmp;
00476 }
00477 }
00478
00485 size_t ctl_serial_record_size( const ctl_serial* serial, const char* label )
00486 {
00487 size_t size;
00488 assertconst(label,1);
00489 assertobjconst(serial);
00490 size = ctl_serial_total( serial );
00491 if( 0 == size )
00492 return 0;
00493 size += ctl_record_head_size( label, "raw" );
00494 return size;
00495 }
00503 void ctl_serial_record_write( const ctl_serial* from, ctl_serial* to, const char* label )
00504 {
00505 size_t total;
00506 assertobjconst(from);
00507 assertobjptr(to);
00508 assertconst(label,1);
00509 total = ctl_serial_total( from );
00510 if( 0 != total )
00511 {
00512 size_t total = ctl_serial_total( from );
00513 ctl_record_write_begin( "raw", total, to, label );
00514 memcpy( to->curr, from->begin, total );
00515 to->curr += total;
00516 }
00517 }
00525 bool ctl_serial_record_read( ctl_serial* to, ctl_serial* from, const char* label )
00526 {
00527 ctl_serial tmp;
00528 assertobjptr(from);
00529 assertobjptr(to);
00530 assertconst(label,1);
00531 tmp = *from;
00532 if( ctl_record_find( &tmp, label ) )
00533 {
00534 const char* szcontainer = ctl_record_type( &tmp );
00535 if( cstrcmp(char)(szcontainer,"raw") )
00536 ctl_serial_except( from, "ctl_serial_record_read: Not raw data" );
00537 ctl_record_getdata( &tmp );
00538 ctl_serial_init( to, tmp.curr, tmp.end );
00539 return true;
00540 }
00541 return false;
00542 }
00543
00544
00552 size_t char_record_size_string( const char* str, size_t maxsize, const char* label )
00553 {
00554 assertconst(label,1);
00555 assertconst(str,1);
00556 return ctl_record_objarray_head_size( label,"string","char" ) + chssize(char,cstrnlen(char)(str,maxsize));
00557 }
00565 size_t wchar_t_record_size_string( const wchar_t* str, size_t maxsize, const char* label )
00566 {
00567 assertconst(label,1);
00568 assertconst(str,1);
00569 return ctl_record_objarray_head_size( label,"string","wchar_t" ) + chssize(wchar_t,cstrnlen(wchar_t)(str,maxsize));
00570 }
00577 size_t char_record_size_gstring( const ctl_gstring(char)* str, const char* label )
00578 {
00579 assertconst(label,1);
00580 assertobjconst(str);
00581 return ctl_record_objarray_head_size( label,"string","char" ) + chssize(char,ctl_gstring_size(char,str));
00582 }
00589 size_t wchar_t_record_size_gstring( const ctl_gstring(wchar_t)* str, const char* label )
00590 {
00591 assertconst(label,1);
00592 assertobjconst(str);
00593 return ctl_record_objarray_head_size( label,"string","wchar_t" ) + chssize(wchar_t,ctl_gstring_size(wchar_t,str));
00594 }
00595
00596
00605 void char_record_write_string( const char* sz, size_t size, ctl_serial* serial, const char* label )
00606 {
00607 size_t storesize;
00608 assertconst(sz,1);
00609 assertconst(label,1);
00610 assertobjptr(serial);
00611 storesize = cstrnlen(char)(sz,size);
00612 assert( serial->curr + storesize <= serial->end );
00613 ctl_record_write_container_begin( "string", "char", storesize,storesize, serial, label );
00614 memcpy( serial->curr, sz, storesize );
00615 serial->curr += storesize;
00616 }
00625 void wchar_t_record_write_string( const wchar_t* sz, size_t size, ctl_serial* serial, const char* label )
00626 {
00627 size_t storesize;
00628 assertconst(sz,1);
00629 assertconst(label,1);
00630 assertobjptr(serial);
00631 storesize = cstrnlen(wchar_t)(sz,size);
00632 ctl_record_write_container_begin( "string", "wchar_t", chssize(wchar_t,storesize),storesize, serial, label );
00633 {
00634 pointer_foreach_const( wchar_t, sz, storesize, curr )
00635 {
00636 uint16 ch = (uint16)*curr;
00637 uint16_serial_write( &ch, serial );
00638 }
00639 }
00640 }
00641
00650 bool char_record_read_string( char* sz, size_t size, const ctl_serial* serial, const char* label )
00651 {
00652 ctl_serial tmp;
00653 assertptr(sz,size);
00654 assertconst(label,1);
00655 assertobjconst(serial);
00656 tmp = *serial;
00657 if( ctl_record_find( &tmp, label ) )
00658 {
00659 const char* szcontainer = ctl_record_type( &tmp );
00660 if( cstrcmp(char)(szcontainer,"string") )
00661 ctl_serial_except( serial, "char_record_read_string: Not a string" );
00662 {
00663 const char* szt = ctl_record_contained_type( &tmp );
00664 size_t rsize = ctl_record_getdata( &tmp );
00665 if( !cstrcmp(char)(szt,"char") )
00666 {
00667 memcpy( sz, tmp.curr, min(size,rsize) );
00668 if( size > rsize )
00669 sz[rsize] = 0;
00670 }
00671 else if( !cstrcmp(char)(szt,"type") )
00672 {
00673 while( size-- && tmp.curr < tmp.end )
00674 {
00675 uint16 ch;
00676 uint16_serial_read( &ch, &tmp );
00677 *sz++ = (char)ch;
00678 }
00679 if( size > 0 )
00680 *sz++ = 0;
00681 }
00682 else
00683 {
00684 ctl_serial_except( serial, "char_record_read_string: Unknown character type" );
00685 }
00686 }
00687 return true;
00688 }
00689 return false;
00690 }
00691
00700 bool wchar_t_record_read_string( wchar_t* sz, size_t size, const ctl_serial* serial, const char* label )
00701 {
00702 ctl_serial tmp;
00703 assertconst(sz,1);
00704 assertconst(label,1);
00705 assertobjconst(serial);
00706 tmp = *serial;
00707 if( ctl_record_find( &tmp, label ) )
00708 {
00709 const char* szcontainer = ctl_record_type( &tmp );
00710 if( cstrcmp(char)(szcontainer,"string") )
00711 ctl_serial_except( serial, "wchar_t_record_read_string: Not a string" );
00712 {
00713 const char* szwchar_t = ctl_record_contained_type( &tmp );
00714 ctl_record_getdata( &tmp );
00715 if( !cstrcmp(char)(szwchar_t,"char") )
00716 {
00717 const char* psz = (const char*)tmp.curr;
00718 while( size-- && tmp.curr < tmp.end )
00719 *sz++ = (wchar_t)*psz++;
00720 if( size > 0 )
00721 *sz++ = 0;
00722 }
00723 else if( !cstrcmp(char)(szwchar_t,"wchar_t") )
00724 {
00725 while( size-- && tmp.curr < tmp.end )
00726 {
00727 uint16 ch;
00728 uint16_serial_read( &ch, &tmp );
00729 *sz++ = (wchar_t)ch;
00730 }
00731 if( size > 0 )
00732 *sz++ = 0;
00733 }
00734 else
00735 {
00736 ctl_serial_except( serial, "wchar_t_record_read_string: Unknown character wchar_t" );
00737 }
00738 }
00739 return true;
00740 }
00741 return false;
00742 }
00743
00751 bool char_record_read_gstring( ctl_gstring(char)* str, const ctl_serial* serial, const char* label )
00752 {
00753 ctl_serial tmp;
00754 assertobjptr(str);
00755 assertconst(label,1);
00756 assertobjconst(serial);
00757 tmp = *serial;
00758 if( ctl_record_find( &tmp, label ) )
00759 {
00760 const char* szcontainer = ctl_record_type( &tmp );
00761 if( cstrcmp(char)(szcontainer,"string") )
00762 ctl_serial_except( serial, "char_record_read_string: Not a string" );
00763 {
00764 const char* sz = ctl_record_contained_type( &tmp );
00765 size_t rsize = ctl_record_getdata( &tmp );
00766 if( !cstrcmp(char)(sz,"char") )
00767 {
00768 ctl_gstring_resize(char, str, ctl_chlength(char,rsize) );
00769 memcpy( str->begin, tmp.curr, rsize );
00770 }
00771 else if( !cstrcmp(char)(sz,"wchar_t") )
00772 {
00773 char* sz;
00774 if( rsize & 1 )
00775 ctl_serial_except( serial, "char_record_read_string: Odd string length" );
00776 ctl_gstring_resize(char, str, chslength(wchar_t,rsize) );
00777 sz = str->begin;
00778 while( tmp.curr < tmp.end )
00779 {
00780 uint16 ch;
00781 uint16_serial_read( &ch, &tmp );
00782 *sz++ = (char)ch;
00783 }
00784 }
00785 else
00786 {
00787 ctl_serial_except( serial, "char_record_read_string: Unknown character type" );
00788 }
00789 }
00790 return true;
00791 }
00792 return false;
00793 }
00794
00802 bool wchar_t_record_read_gstring( ctl_gstring(wchar_t)* str, const ctl_serial* serial, const char* label )
00803 {
00804 ctl_serial tmp;
00805 assertobjptr(str);
00806 assertconst(label,1);
00807 assertobjconst(serial);
00808 tmp = *serial;
00809 if( ctl_record_find( &tmp, label ) )
00810 {
00811 const char* szcontainer = ctl_record_type( &tmp );
00812 if( cstrcmp(char)(szcontainer,"string") )
00813 ctl_serial_except( serial, "wchar_t_record_read_string: Not a string" );
00814 {
00815 const char* szwchar_t = ctl_record_contained_type( &tmp );
00816 size_t rsize = ctl_record_getdata( &tmp );
00817 if( !cstrcmp(char)(szwchar_t,"char") )
00818 {
00819 wchar_t* sz;
00820 const char* psz = (const char*)tmp.curr;
00821 ctl_gstring_resize(wchar_t, str, rsize );
00822 sz = str->begin;
00823 while( tmp.curr < tmp.end )
00824 *sz++ = (wchar_t)*psz++;
00825 }
00826 else if( !cstrcmp(char)(szwchar_t,"wchar_t") )
00827 {
00828 wchar_t* sz;
00829 if( rsize & 1 )
00830 ctl_serial_except( serial, "wchar_t_record_read_string: Odd string length" );
00831 rsize = chslength(wchar_t,rsize);
00832 ctl_gstring_resize(wchar_t, str, rsize );
00833 sz = str->begin;
00834 while( tmp.curr < tmp.end )
00835 {
00836 uint16 ch;
00837 uint16_serial_read( &ch, &tmp );
00838 *sz++ = (wchar_t)ch;
00839 }
00840 }
00841 else
00842 {
00843 ctl_serial_except( serial, "wchar_t_record_read_string: Unknown character wchar_t" );
00844 }
00845 }
00846 return true;
00847 }
00848 return false;
00849 }
00850
00851 #if 1
00852
00853 void spew1();
00854
00855 #define X_RECORD_READ(type,unused)\
00856 \
00864 bool ppConcat(type,_record_read)( type* pdata, const ctl_serial* serial, const char* label ) \
00865 {\
00866 ctl_serial tmp;\
00867 assertconst(label,1);\
00868 assertobjconst(serial);\
00869 assertptr(pdata,sizeof(type));\
00870 tmp = *serial;\
00871 if( ctl_record_find( &tmp, label ) )\
00872 {\
00873 const char* sz = ctl_record_type( &tmp );\
00874 ctl_record_getdata( &tmp );\
00875 DEF_ENUMTYPES_INNER(X_SCALAR_TYPES,type)\
00876 {\
00877 ctl_serial_except( serial, #type "_record_read: Invalid scalar type" );\
00878 }\
00879 }\
00880 return false;\
00881 }
00882 #define X_SCALAR_TYPES(type,outertype)\
00883 if( !strcmp(sz,#type) )\
00884 {\
00885 type ppConcat(get_,type);\
00886 ppConcat(type,_serial_read)( &ppConcat(get_,type), &tmp );\
00887 ppConcat(outertype,_copy_t)(*pdata,type,ppConcat(get_,type));\
00888 return true;\
00889 }\
00890 else
00891
00892 DEF_ENUMTYPES(X_RECORD_READ,unused)
00893 #undef X_RECORD_READ
00894 #undef X_SCALAR_TYPES
00895
00896
00897
00898
00899 #define X_RECORD_WRITE(type,unused) \
00900 void ppConcat(type,_record_write)( const type* pdata, ctl_serial* serial, const char* label )\
00901 {\
00902 assertconst(label,1);\
00903 assertobjptr(serial);\
00904 assertconst(pdata,sizeof(type));\
00905 ctl_record_write_begin( #type, ppConcat(type,_serial_size)( p ), serial, label );\
00906 ppConcat(type,_serial_write)( pdata, serial );\
00907 }
00908 DEF_ENUMTYPES(X_RECORD_WRITE,unused)
00909 #undef X_RECORD_WRITE
00910
00911 #define X_RECORD_ARRAY_WRITE(type,unused) \
00912 void ppConcat(type,_record_writearray)( const type* pdata, size_t count, ctl_serial* serial, const char* label )\
00913 {\
00914 assertconst(label,1);\
00915 assertobjptr(serial);\
00916 assertconst(pdata,sizeof(type));\
00917 ctl_record_write_container_begin( "array", #type, ppConcat(type,_serial_size)( p )*count, count, serial, label );\
00918 {\
00919 pointer_foreach_const( type, pdata, count, curr )\
00920 ppConcat(type,_serial_write)( curr, serial );\
00921 }\
00922 }
00923 DEF_ENUMTYPES(X_RECORD_ARRAY_WRITE,unused)
00924 #undef X_RECORD_ARRAY_WRITE
00925
00926 #define X_RECORD_ARRAY_READ(type,unused) \
00927 \
00936 bool ppConcat(type,_record_readarray)( type* pdata, size_t count, const ctl_serial* serial, const char* label )\
00937 {\
00938 ctl_serial tmp;\
00939 assertconst(label,1);\
00940 assertobjconst(serial);\
00941 assertptr(pdata,count*sizeof(type));\
00942 tmp = *serial;\
00943 if( ctl_record_find( &tmp, label ) )\
00944 {\
00945 \
00946 const char* sz = ctl_record_contained_type( &tmp );\
00947 size_t rsize = ctl_record_getdata( &tmp );\
00948 DEF_ENUMTYPES_INNER(X_SCALAR_TYPES,type)\
00949 {\
00950 ctl_serial_except( serial, #type "_record_readarray: Invalid scalar type" );\
00951 }\
00952 }\
00953 return false;\
00954 }
00955 #define X_SCALAR_TYPES(type,outertype)\
00956 if( !strcmp(sz,#type) )\
00957 {\
00958 if( rsize % ppConcat(type,_serial_size)( 0 ) )\
00959 ctl_serial_except( serial, #outertype "_record_readarray: Odd length array" );\
00960 {\
00961 size_t scount = rsize / ppConcat(type,_serial_size)( 0 );\
00962 if( scount > count )\
00963 scount = count;\
00964 {\
00965 pointer_foreach( outertype, pdata, scount, curr )\
00966 {\
00967 type ppConcat(get_,type);\
00968 ppConcat(type,_serial_read)( &ppConcat(get_,type), &tmp );\
00969 ppConcat(outertype,_copy_t)(*pdata,type,ppConcat(get_,type));\
00970 pdata++;\
00971 }\
00972 return true;\
00973 }\
00974 }\
00975 }\
00976 else
00977
00978 DEF_ENUMTYPES(X_RECORD_ARRAY_READ,unused)
00979 #undef X_RECORD_ARRAY_READ
00980 #undef X_SCALAR_TYPES
00981
00982 #else
00983
00984 void spew0();
00985
00986 #endif