BufferOperation.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. #ifndef CBufferOperation_h
  2. #define CBufferOperation_h
  3. #include "SimpleString.h"
  4. #include "AutoArray.h"
  5. #include "Blob.h"
  6. namespace Chromium{
  7. #define IOBUF_T_I8 0
  8. #define IOBUF_T_I4 1
  9. #define IOBUF_T_I2 2
  10. #define IOBUF_T_I1 3
  11. #define IOBUF_T_STR 4
  12. #define IOBUF_T_BUF 5
  13. #define IOBUF_T_WSTR 6
  14. #define IOBUF_T_7BIT 7
  15. /////////////////// Read Buf Start ///////////////////////
  16. static void buffer_read_buf(const char *iobuf, char *buf, int n, int* rpos)
  17. {
  18. // assert(content_size(iobuf) >= n);
  19. memcpy(buf, iobuf + *rpos, n);
  20. *rpos += n;
  21. }
  22. static void buffer_read_7bit_int(const char *iobuf, int *v, int* rpos)
  23. {
  24. int count = 0;
  25. int shift = 0;
  26. unsigned char b;
  27. do {
  28. if (shift == 5*7) // corrupted stream
  29. assert(0);
  30. b = iobuf[*rpos];
  31. *rpos += 1;
  32. count |= (b & 0x7F) << shift;
  33. shift += 7;
  34. } while (b & 0x80); // most left bit is flag
  35. *v = count;
  36. }
  37. static void buffer_read(const char *iobuf, int t, void *v, int *n, int* rpos){
  38. int len = 0;
  39. switch (t)
  40. {
  41. case IOBUF_T_I8:
  42. len += 8;
  43. buffer_read_buf(iobuf, (char*)v, len, rpos);
  44. break;
  45. case IOBUF_T_I4:
  46. len += 4;
  47. buffer_read_buf(iobuf, (char*)v, len, rpos);
  48. break;
  49. case IOBUF_T_I2:
  50. len += 2;
  51. buffer_read_buf(iobuf, (char*)v, len, rpos);
  52. break;
  53. case IOBUF_T_I1:
  54. len += 1;
  55. buffer_read_buf(iobuf, (char*)v, len, rpos);
  56. break;
  57. case IOBUF_T_STR:
  58. if (v) {
  59. int old_rpos = *rpos;
  60. buffer_read_7bit_int(iobuf, &len, rpos);
  61. if (!n || len < *n) {
  62. buffer_read_buf(iobuf, (char *)v, len, rpos);
  63. *((char*)v + len) = 0;
  64. if (n)
  65. *n = len;
  66. } else {
  67. *rpos = old_rpos;
  68. *n = len;
  69. }
  70. } else {
  71. if (n) {
  72. int old_rpos = *rpos;
  73. buffer_read_7bit_int(iobuf, &len, rpos);
  74. *rpos = old_rpos;
  75. *n = len;
  76. } else {
  77. assert(0);
  78. }
  79. }
  80. break;
  81. case IOBUF_T_WSTR:
  82. if (v) {
  83. int old_rpos = *rpos;
  84. buffer_read_7bit_int(iobuf, &len, rpos);
  85. if (!n || len < *n) {
  86. buffer_read_buf(iobuf, (char*)v, len, rpos);
  87. memset((void*)((char*)v + len), 0, sizeof(wchar_t));
  88. if (n)
  89. *n = len;
  90. } else {
  91. *rpos = old_rpos;
  92. *n = len;
  93. }
  94. } else {
  95. if (n) {
  96. int old_rpos = *rpos;
  97. buffer_read_7bit_int(iobuf, &len, rpos);
  98. *rpos = old_rpos;
  99. *n = len;
  100. } else {
  101. assert(0);
  102. }
  103. }
  104. break;
  105. case IOBUF_T_BUF:
  106. if (*n > 0)
  107. buffer_read_buf(iobuf, (char*)v, *n, rpos);
  108. break;
  109. case IOBUF_T_7BIT:
  110. buffer_read_7bit_int(iobuf, (int*)v, rpos);
  111. break;
  112. default:
  113. assert(0);
  114. }
  115. }
  116. void buffer_format_readv(const char *iobuf, int* rpos, const char *fmt, va_list arg)
  117. {
  118. if (fmt) {
  119. const char *p = fmt;
  120. while (*p) {
  121. switch (*p) {
  122. case '8':
  123. buffer_read(iobuf, IOBUF_T_I8, va_arg(arg, void*), NULL, rpos);
  124. break;
  125. case '7': // 7bit int code
  126. buffer_read(iobuf, IOBUF_T_7BIT, va_arg(arg, void*), NULL, rpos);
  127. break;
  128. case '4':
  129. buffer_read(iobuf, IOBUF_T_I4, va_arg(arg, void*), 0, rpos);
  130. break;
  131. case '2':
  132. buffer_read(iobuf, IOBUF_T_I2, va_arg(arg, void*), 0, rpos);
  133. break;
  134. case '1':
  135. buffer_read(iobuf, IOBUF_T_I1, va_arg(arg, void*), 0, rpos);
  136. break;
  137. case 's':case 'S':
  138. {
  139. char **pstr = va_arg(arg, char**);
  140. int slen;
  141. buffer_read(iobuf, IOBUF_T_STR, NULL, &slen, rpos);
  142. //*pstr = (char*)malloc(slen+1);
  143. *pstr = new char[slen+1];
  144. buffer_read(iobuf, IOBUF_T_STR, *pstr, 0, rpos);
  145. }
  146. break;
  147. case 'w': case 'W':
  148. {
  149. wchar_t** pstr = va_arg(arg, wchar_t**);
  150. int slen;
  151. buffer_read(iobuf, IOBUF_T_WSTR, NULL, &slen, rpos);
  152. *pstr = new wchar_t[slen+1];
  153. buffer_read(iobuf, IOBUF_T_WSTR, *pstr, 0, rpos);
  154. }
  155. break;
  156. case 'b':case 'B':
  157. {
  158. void *buf = va_arg(arg, void*);
  159. int size = va_arg(arg, int);
  160. buffer_read(iobuf, IOBUF_T_BUF, buf, &size, rpos);
  161. }
  162. break;
  163. default:
  164. assert(0);
  165. break;
  166. }
  167. p++;
  168. }
  169. }
  170. }
  171. class BufferFormatRead{
  172. public:
  173. static void buffer_format_read(const char *iobuf, int* rpos, const char *fmt, ...)
  174. {
  175. va_list arg;
  176. va_start(arg, fmt);
  177. buffer_format_readv(iobuf, rpos, fmt, arg);
  178. va_end(arg);
  179. }
  180. };
  181. template<class T>
  182. static inline void ReadT(const char *iobuf, T &t, int* rpos){
  183. int size = sizeof(t);
  184. buffer_read(iobuf, IOBUF_T_BUF, &t, &size, rpos);
  185. }
  186. static inline void ReadT(const char *iobuf, void* data, int &len, int* rpos){
  187. buffer_read(iobuf, IOBUF_T_BUF, data, &len, rpos);
  188. }
  189. template<class T>
  190. static inline void ReadArrayT(const char *iobuf, CAutoArray<T> &t, int* rpos){
  191. int nArrayNum(0);
  192. buffer_read(iobuf, IOBUF_T_I4, &nArrayNum, NULL, rpos);
  193. if (nArrayNum >0)
  194. {
  195. t.Init(nArrayNum);
  196. for(int i=0; i<nArrayNum; i++)
  197. {
  198. ReadT(iobuf, t[i], rpos);
  199. }
  200. }
  201. }
  202. static inline void ReadT(const char *iobuf, CSimpleStringA &t, int* rpos){
  203. SPCHAR *wt = NULL;
  204. BufferFormatRead::buffer_format_read(iobuf, rpos, "w", &wt); // string is unicode so we can compatible with silverlight
  205. CSimpleStringW wStr = wt;
  206. free(wt);
  207. t = CSimpleStringW2A(wStr);
  208. }
  209. static inline void ReadT(const char *iobuf, CSimpleStringW &t, int* rpos){
  210. SPCHAR*wt = NULL;
  211. BufferFormatRead::buffer_format_read(iobuf, rpos, "w", &wt); // string is unicode so we can compatible with silverlight
  212. t = wt;
  213. free(wt);
  214. }
  215. /////////////////// Read Buf End///////////////////////
  216. ////////////////// Write Buffer Start /////////////////////
  217. static void expand(char *iobuf, int head_capacity, int newcapacity,
  218. int *capacity, int *hcapacity, int* rpos, int* wpos)
  219. {
  220. if (head_capacity == -1) {
  221. int t = *capacity;
  222. while (newcapacity > t)
  223. t = t*2;
  224. if (t > *capacity) {
  225. iobuf = (char*)realloc(iobuf, t);
  226. *capacity = t;
  227. }
  228. } else if (newcapacity == -1) {
  229. int t = *hcapacity;
  230. while (head_capacity > t)
  231. t = t*2;
  232. if (t > *rpos) {
  233. char *new_data;
  234. int new_rpos;
  235. int new_wpos;
  236. newcapacity = *capacity + (t - *hcapacity);
  237. // new_data = (char*)malloc(newcapacity);
  238. new_data = new char[newcapacity];
  239. new_rpos = t;
  240. new_wpos = new_rpos + (*wpos - *rpos);
  241. memcpy(new_data+new_rpos, iobuf+*rpos, *wpos - *rpos);
  242. free(iobuf);
  243. iobuf = new_data;
  244. *rpos = new_rpos;
  245. *wpos = new_wpos;
  246. *hcapacity = t;
  247. *capacity = newcapacity;
  248. }
  249. } else {
  250. int t = *capacity;
  251. // char *new_data = (char*)malloc(t);
  252. char *new_data = new char[t];
  253. int new_rpos = head_capacity;
  254. int new_wpos = new_rpos + (*wpos - *rpos);
  255. while (newcapacity > t)
  256. t = t*2;
  257. memcpy(new_data+new_rpos, iobuf+*rpos, *wpos - *rpos);
  258. free(iobuf);
  259. iobuf = new_data;
  260. *rpos = new_rpos;
  261. *wpos = new_wpos;
  262. *capacity = t;
  263. }
  264. }
  265. static void buffer_write_buf(char *iobuf, const char *buf, int n, int* wpos, int* capacity)
  266. {
  267. int rpos = 0;
  268. int hcapacity = 0;
  269. if ( n+(*wpos) > *capacity )
  270. expand(iobuf, -1, n + *wpos, capacity, &hcapacity, &rpos, wpos);
  271. memcpy(iobuf+*wpos, buf, n);
  272. *wpos += n;
  273. }
  274. static int write_7bit_int(unsigned char buf[8], unsigned int v)
  275. {
  276. int i = 0;
  277. while (v >= 0x80) {
  278. buf[i++] = (unsigned char)(v | 0x80); // set most left bit == 1
  279. v >>= 7;
  280. }
  281. buf[i++] = (unsigned char)v;
  282. return i;
  283. }
  284. static void buffer_write_7bit_int(char *iobuf, unsigned int v, int* wpos, int* capacity)
  285. {
  286. char buf[8];
  287. int n = write_7bit_int((unsigned char*)buf, v);
  288. buffer_write_buf(iobuf, buf, n, wpos, capacity);
  289. }
  290. void buffer_write(char *iobuf, int t, const void *v, int n, int* wpos, int* capacity)
  291. {
  292. int len = 0;
  293. switch (t) {
  294. case IOBUF_T_I8:
  295. len += 8;
  296. buffer_write_buf(iobuf, (const char*)v, len, wpos, capacity);
  297. break;
  298. case IOBUF_T_I4:
  299. len += 4;
  300. buffer_write_buf(iobuf, (const char*)v, len, wpos, capacity);
  301. break;
  302. case IOBUF_T_I2:
  303. len += 2;
  304. buffer_write_buf(iobuf, (const char*)v, len, wpos, capacity);
  305. break;
  306. case IOBUF_T_I1:
  307. len += 1;
  308. buffer_write_buf(iobuf, (const char*)v, len, wpos, capacity);
  309. break;
  310. case IOBUF_T_STR:
  311. if (!v) {
  312. n = 0;
  313. } else {
  314. if (n == -1)
  315. n = strlen((const char*)v);
  316. }
  317. buffer_write_7bit_int(iobuf, (unsigned int)n, wpos, capacity);
  318. if (n > 0)
  319. buffer_write_buf(iobuf, (const char*)v, n, wpos, capacity);
  320. break;
  321. case IOBUF_T_WSTR:
  322. if (!v) {
  323. n = 0;
  324. } else {
  325. if (n == -1)
  326. n = wcslen((const wchar_t*)v) << 2;
  327. }
  328. buffer_write_7bit_int(iobuf, n, wpos, capacity);
  329. if (n > 0)
  330. buffer_write_buf(iobuf, (const char*)v, n, wpos, capacity);
  331. break;
  332. case IOBUF_T_BUF:
  333. if (n > 0)
  334. buffer_write_buf(iobuf, (const char*)v, n, wpos, capacity);
  335. break;
  336. case IOBUF_T_7BIT:
  337. buffer_write_7bit_int(iobuf, *(unsigned int*)v, wpos, capacity);
  338. break;
  339. default:
  340. assert(0);
  341. break;
  342. }
  343. }
  344. template<class T>
  345. static inline void WriteT(char *iobuf, T &t, int* wpos, int* capacity)
  346. {
  347. buffer_write(iobuf, IOBUF_T_BUF, &t, sizeof(t), wpos, capacity);
  348. }
  349. template<class T>
  350. static inline void WriteArrayT(char *iobuf, CAutoArray<T> &t, int* wpos, int* capacity)
  351. {
  352. int nArrayNum = t.GetCount();
  353. buffer_write(iobuf, IOBUF_T_I4, &nArrayNum, 0, wpos, capacity);
  354. for(int i=0; i<nArrayNum; i++)
  355. {
  356. WriteT(iobuf, t[i], wpos, capacity);
  357. }
  358. }
  359. template<class T>
  360. static inline void WriteArrayT(char *iobuf, const CAutoArray<T> &t, int* wpos, int* capacity)
  361. {
  362. int nArrayNum = t.GetCount();
  363. buffer_write(iobuf, IOBUF_T_I4, &nArrayNum, 0, wpos, capacity);
  364. for(int i=0; i<nArrayNum; i++)
  365. {
  366. WriteT(iobuf, t[i], wpos, capacity);
  367. }
  368. }
  369. static inline void WriteT(char *iobuf, CSimpleStringA &t, int* wpos, int* capacity)
  370. {
  371. CSimpleStringW wt = CSimpleStringA2W(t); // string is unicode so we can compatible with silverlight
  372. buffer_write(iobuf, IOBUF_T_WSTR, wt.GetData(), -1, wpos, capacity);
  373. }
  374. static inline void WriteT(char *iobuf, CSimpleStringW &t, int* wpos, int* capacity)
  375. {
  376. buffer_write(iobuf, IOBUF_T_WSTR, t.GetData(), -1, wpos, capacity);
  377. }
  378. static inline void WriteT(char *iobuf, const CSimpleStringA &t, int* wpos, int* capacity)
  379. {
  380. CSimpleStringW wt = CSimpleStringA2W(t); // string is unicode so we can compatible with silverlight
  381. buffer_write(iobuf, IOBUF_T_WSTR, wt.GetData(), -1, wpos, capacity);
  382. }
  383. static inline void WriteT(char *iobuf, const CSimpleStringW &t, int* wpos, int* capacity)
  384. {
  385. buffer_write(iobuf, IOBUF_T_WSTR, t.GetData(), -1, wpos, capacity);
  386. }
  387. static inline void WriteT(char *iobuf, char* t, int* wpos, int* capacity, int len)
  388. {
  389. buffer_write(iobuf, IOBUF_T_BUF, t, len, wpos, capacity);
  390. }
  391. // static inline void WriteT(char *iobuf, CBlob &t)
  392. // {
  393. // // iobuffer_write(iobuf, IOBUF_T_I4, &t.m_iLength, 0);
  394. // // iobuffer_write(iobuf, IOBUF_T_BUF, t.m_pData, t.m_iLength);
  395. // }
  396. //
  397. //
  398. // static inline void WriteT(char *iobuf, const CBlob &t)
  399. // {
  400. // // iobuffer_write(iobuf, IOBUF_T_I4, &t.m_iLength, 0);
  401. // // iobuffer_write(iobuf, IOBUF_T_BUF, t.m_pData, t.m_iLength);
  402. // }
  403. ///////////////// Write Buffer End //////////////////////
  404. }
  405. #endif