在我創業的一個項目中,為了節約網絡帶寬,因此在網絡中傳輸數據需要實現緊湊存取,在國防,科研,航天,軍工等多個領域其實也有類似的需求。
實現緊湊存取,不是按一個字節一個字節地存取,而是按位存取。比如一個字節,我們可以存儲8個bool信息,廢話少說,直接分享代碼(備注:里面的代碼算法值得優化)。
//以下為函數定義
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
/***********************************************************************/ /* 函數作用:從buffer讀一個位 */ /* 參數pBuffer[in]:指定buffer */ /* 參數nStart[in]:指定位置 */ /* 參數nEnd[out]:返回結束位置 */ /* 參數retByte[out]:返回讀取結果值 */ /* 返回:void */ /***********************************************************************/ void ReadOneBit( byte* pBuffer, int nStart, /* out */ int & nEnd, /* out */ byte& retByte ); /***********************************************************************/ /* 函數作用:從指定buffer里讀任意一段位置數據 */ /* 參數pBuffer[in]:指定buffer */ /* 參數nStart[in]:指定位置 */ /* 參數btLength[in]:讀取長度 */ /* 參數nEnd[out]:返回結束位置 */ /* 參數retData[out]:返回讀取結果值,支持任意數據類型 */ /* 返回:void */ /***********************************************************************/ template < typename T> void ReadDataFromBuffer( byte* pBuffer, int nStart, byte btLength, /* out */ int & nEnd, /* out */ T& retData ); /***********************************************************************/ /* 函數作用:從指定buffer里讀取一段字符串 */ /* 參數pBuffer[in]:指定buffer */ /* 參數nStart[in]:指定位置 */ /* 參數nCount[in]:字符串長度 */ /* 參數nEnd[out]:返回結束位置 */ /* 參數pRetData[out]:返回讀取字符串結果 */ /* 返回:void */ /***********************************************************************/ void ReadStringFromBuffer( byte* pBuffer, int nStart, int nCount, /* out */ int & nEnd, /* out */ char * pRetData ); /***********************************************************************/ /* 函數作用:向buffer寫一個位 */ /* 參數pBuffer[in]:指定buffer */ /* 參數btData[in]:需要寫入的值 */ /* 參數nStart[in]:指定位置 */ /* 參數nEnd[out]:返回結束位置 */ /* 返回:void */ /***********************************************************************/ void WriteOneBit( byte* pBuffer, byte btData, int nStart, /* out */ int & nEnd ); /***********************************************************************/ /* 函數作用:向指定buffer里寫入任意一段數據 */ /* 參數pBuffer[in]:指定buffer */ /* 參數tData[in]:需要寫入的數據,支持任意數據類型 */ /* 參數nStart[in]:指定位置 */ /* 參數btLength[in]:讀取長度 */ /* 參數nEnd[out]:返回結束位置 */ /* 返回:void */ /***********************************************************************/ template < typename T> void WriteDataToBuffer( byte* pBuffer, T tData, int nStart, byte btLength, /* out */ int & nEnd ); /***********************************************************************/ /* 函數作用:向指定buffer里寫取一段字符串 */ /* 參數pBuffer[in]:指定buffer */ /* 參數pchar[in]:需要寫入的字符串 */ /* 參數nStart[in]:指定位置 */ /* 參數nCount[in]:字符串長度 */ /* 參數nEnd[out]:返回結束位置 */ /* 返回:void */ /***********************************************************************/ void WtriteStringToBuffer( byte* pBuffer, char * pchar, int nStart, int nCount, /* out */ int & nEnd ); |
//以下為函數實現
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
void ReadOneBit( byte* pBuffer, int nStart, /* out */ int & nEnd, /* out */ byte& retByte ) { byte btData = pBuffer[nStart/8]; btData = btData << nStart%8; retByte = btData >> 7; nEnd = nStart+1; } template < typename T> void ReadDataFromBuffer( byte* pBuffer, int nStart, byte btLength, /* out */ int & nEnd, /* out */ T& retData ) { //順序讀位 retData = 0; if ( btLength > sizeof (T)*8 ) return ; byte btData; T tData; while ( btLength-- ) { ReadOneBit(pBuffer, nStart, nStart, btData); tData = btData << btLength; retData |= tData; } nEnd = nStart; } void ReadStringFromBuffer( byte* pBuffer, int nStart, int nCount, /* out */ int & nEnd, /* out */ char * pRetData ) { for ( int nIndex=0; nIndex<nCount; nIndex++ ) { ReadDataFromBuffer(pBuffer, nStart, 8, nStart, pRetData[nIndex]); } nEnd = nStart; } void WriteOneBit( byte* pBuffer, byte btData, int nStart, /* out */ int & nEnd ) { int nSet = nStart / 8; byte c = pBuffer[nSet]; switch ( btData ) { case 1: c |= ( 1 << (7- nStart % 8) ); break ; case 0: c &= ( ~(1 << (7- nStart % 8) ) ); break ; default : return ; } pBuffer [nSet] = c; nEnd = nStart +1; } template < typename T> void WriteDataToBuffer( byte* pBuffer, T tData, int nStart, byte btLength, /* out */ int & nEnd ) { /* //大端機模式 byte btDataLength = sizeof(T); if ( btLength > sizeof(T)*8 ) return; int nDataStart = 0; //數據的第一位位置為0,順序寫入 while ( btLength-- ) { byte bitData; ReadOneBit((byte*)&tData, nDataStart, nDataStart, bitData); WriteOneBit(pBuffer, bitData, nStart, nStart); } nEnd = nStart; */ //小端機模式:寫buffer的時候,不能順序寫位 //獲得模版占用字節大小 byte btDataLength = sizeof (T); //校驗長度是否越界 if ( btLength > sizeof (T)*8 ) return ; //將待寫數據轉為byte* byte* ptData = (byte*)&tData; //求模與余 int nSet = btLength / 8; int nRin = btLength % 8; //定義字節數據與位數據 byte bitData; byte byteData; int nTempEnd; //先寫rin數據 byteData = ptData[nSet]; while ( nRin-- ) { ReadOneBit(&byteData, 7-nRin, nTempEnd, bitData); WriteOneBit(pBuffer, bitData, nStart, nStart); } //再寫Set數據 while ( nSet ) { byteData = ptData[--nSet]; //寫一個byte int i=0; while ( i!=8 ) { ReadOneBit(&byteData, i++, nTempEnd, bitData); WriteOneBit(pBuffer, bitData, nStart, nStart); } } nEnd = nStart; } void WtriteStringToBuffer( byte* pBuffer, char * pchar, int nStart, int nCount, /* out */ int & nEnd ) { for ( int nIndex=0; nIndex<nCount; nIndex++ ) { WriteDataToBuffer(pBuffer, pchar[nIndex], nStart, 8, nStart); } nEnd = nStart; } |
以上就是本文的全部內容,希望對大家的學習有所幫助。