lldatapacker.cpp 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065
  1. /**
  2. * @file lldatapacker.cpp
  3. * @brief Data packer implementation.
  4. *
  5. * $LicenseInfo:firstyear=2006&license=viewergpl$
  6. *
  7. * Copyright (c) 2006-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #include "linden_common.h"
  33. #include "lldatapacker.h"
  34. #include "llcolor4.h"
  35. #include "llcolor4u.h"
  36. #include "llmessage.h"
  37. #include "llvector2.h"
  38. #include "llvector3.h"
  39. #include "llvector4.h"
  40. // *NOTE: there are functions below which use sscanf and rely on this
  41. // particular value of DP_BUFSIZE. Search for '511' (DP_BUFSIZE - 1) to find
  42. // them if you change this number.
  43. constexpr S32 DP_BUFSIZE = 512;
  44. static char DUMMY_BUFFER[128];
  45. LLDataPacker::LLDataPacker()
  46. : mPassFlags(0),
  47. mWriteEnabled(false)
  48. {
  49. }
  50. //virtual
  51. void LLDataPacker::reset()
  52. {
  53. llerrs << "Using unimplemented datapacker reset !" << llendl;
  54. }
  55. //virtual
  56. void LLDataPacker::dumpBufferToLog()
  57. {
  58. llerrs << "Not implemented for this type !" << llendl;
  59. }
  60. bool LLDataPacker::packFixed(F32 value, const char* name, bool is_signed,
  61. U32 int_bits, U32 frac_bits)
  62. {
  63. bool success = true;
  64. S32 unsigned_bits = int_bits + frac_bits;
  65. S32 total_bits = unsigned_bits;
  66. if (is_signed)
  67. {
  68. ++total_bits;
  69. }
  70. S32 min_val;
  71. U32 max_val;
  72. if (is_signed)
  73. {
  74. min_val = 1 << int_bits;
  75. min_val *= -1;
  76. }
  77. else
  78. {
  79. min_val = 0;
  80. }
  81. max_val = 1 << int_bits;
  82. // Clamp to be within range
  83. F32 fixed_val = llclamp(value, (F32)min_val, (F32)max_val);
  84. if (is_signed)
  85. {
  86. fixed_val += max_val;
  87. }
  88. fixed_val *= 1 << frac_bits;
  89. if (total_bits <= 8)
  90. {
  91. success = packU8((U8)fixed_val, name);
  92. }
  93. else if (total_bits <= 16)
  94. {
  95. success = packU16((U16)fixed_val, name);
  96. }
  97. else if (total_bits <= 31)
  98. {
  99. success = packU32((U32)fixed_val, name);
  100. }
  101. else
  102. {
  103. llerrs << "Using fixed-point packing of " << total_bits
  104. << " bits, why ?!" << llendl;
  105. }
  106. return success;
  107. }
  108. bool LLDataPacker::unpackFixed(F32& value, const char* name, bool is_signed,
  109. U32 int_bits, U32 frac_bits)
  110. {
  111. bool ok = false;
  112. S32 unsigned_bits = int_bits + frac_bits;
  113. S32 total_bits = unsigned_bits;
  114. if (is_signed)
  115. {
  116. ++total_bits;
  117. }
  118. U32 max_val;
  119. max_val = 1 << int_bits;
  120. F32 fixed_val;
  121. if (total_bits <= 8)
  122. {
  123. U8 fixed_8;
  124. ok = unpackU8(fixed_8, name);
  125. fixed_val = (F32)fixed_8;
  126. }
  127. else if (total_bits <= 16)
  128. {
  129. U16 fixed_16;
  130. ok = unpackU16(fixed_16, name);
  131. fixed_val = (F32)fixed_16;
  132. }
  133. else if (total_bits <= 31)
  134. {
  135. U32 fixed_32;
  136. ok = unpackU32(fixed_32, name);
  137. fixed_val = (F32)fixed_32;
  138. }
  139. else
  140. {
  141. fixed_val = 0;
  142. llerrs << "Bad bit count: " << total_bits << llendl;
  143. }
  144. fixed_val /= (F32)(1 << frac_bits);
  145. if (is_signed)
  146. {
  147. fixed_val -= max_val;
  148. }
  149. value = fixed_val;
  150. return ok;
  151. }
  152. //---------------------------------------------------------------------------
  153. // LLDataPackerBinaryBuffer implementation
  154. //---------------------------------------------------------------------------
  155. void LLDataPackerBinaryBuffer::warnBadLength(S32 data_size, const char* name)
  156. {
  157. llwarns << "Buffer overflow in BinaryBuffer length verify, field name '"
  158. << name << "' ! Current pos: " << (S32)(mCurBufferp - mBufferp)
  159. << " - Buffer size: " << mBufferSize << " - Data size: "
  160. << data_size << llendl;
  161. }
  162. bool LLDataPackerBinaryBuffer::packString(const std::string& value,
  163. const char* name)
  164. {
  165. S32 length = value.length() + 1;
  166. if (!verifyLength(length, name))
  167. {
  168. return false;
  169. }
  170. if (mWriteEnabled)
  171. {
  172. htonmemcpy(mCurBufferp, value.c_str(), MVT_VARIABLE, length);
  173. }
  174. mCurBufferp += length;
  175. return true;
  176. }
  177. bool LLDataPackerBinaryBuffer::unpackString(std::string& value,
  178. const char* name)
  179. {
  180. S32 length = (S32)strlen((char*)mCurBufferp) + 1;
  181. if (!verifyLength(length, name))
  182. {
  183. return false;
  184. }
  185. // We already assume NULL termination calling strlen()
  186. value = std::string((char*)mCurBufferp);
  187. mCurBufferp += length;
  188. return true;
  189. }
  190. bool LLDataPackerBinaryBuffer::packBinaryData(const U8* value, S32 size,
  191. const char* name)
  192. {
  193. if (!verifyLength(size + 4, name))
  194. {
  195. return false;
  196. }
  197. if (mWriteEnabled)
  198. {
  199. htonmemcpy(mCurBufferp, &size, MVT_S32, 4);
  200. }
  201. mCurBufferp += 4;
  202. if (mWriteEnabled)
  203. {
  204. htonmemcpy(mCurBufferp, value, MVT_VARIABLE, size);
  205. }
  206. mCurBufferp += size;
  207. return true;
  208. }
  209. bool LLDataPackerBinaryBuffer::unpackBinaryData(U8* value, S32& size,
  210. const char* name)
  211. {
  212. if (!verifyLength(4, name))
  213. {
  214. llwarns << "Invalid data, aborting !" << llendl;
  215. return false;
  216. }
  217. htonmemcpy(&size, mCurBufferp, MVT_S32, 4);
  218. if (size < 0)
  219. {
  220. llwarns << "Invalid size, aborting !" << llendl;
  221. return false;
  222. }
  223. mCurBufferp += 4;
  224. if (!verifyLength(size, name))
  225. {
  226. llwarns << "Invalid data, aborting !" << llendl;
  227. return false;
  228. }
  229. if (!value)
  230. {
  231. llwarns << "NULL 'value', aborting !" << llendl;
  232. return false;
  233. }
  234. htonmemcpy(value, mCurBufferp, MVT_VARIABLE, size);
  235. mCurBufferp += size;
  236. return true;
  237. }
  238. bool LLDataPackerBinaryBuffer::packBinaryDataFixed(const U8* value, S32 size,
  239. const char* name)
  240. {
  241. if (!verifyLength(size, name))
  242. {
  243. return false;
  244. }
  245. if (mWriteEnabled)
  246. {
  247. htonmemcpy(mCurBufferp, value, MVT_VARIABLE, size);
  248. }
  249. mCurBufferp += size;
  250. return true;
  251. }
  252. bool LLDataPackerBinaryBuffer::unpackBinaryDataFixed(U8* value, S32 size,
  253. const char* name)
  254. {
  255. if (!verifyLength(size, name))
  256. {
  257. return false;
  258. }
  259. htonmemcpy(value, mCurBufferp, MVT_VARIABLE, size);
  260. mCurBufferp += size;
  261. return true;
  262. }
  263. bool LLDataPackerBinaryBuffer::packU8(U8 value, const char* name)
  264. {
  265. if (!verifyLength(sizeof(U8), name))
  266. {
  267. return false;
  268. }
  269. if (mWriteEnabled)
  270. {
  271. *mCurBufferp = value;
  272. }
  273. ++mCurBufferp;
  274. return true;
  275. }
  276. bool LLDataPackerBinaryBuffer::unpackU8(U8 &value, const char* name)
  277. {
  278. if (!verifyLength(sizeof(U8), name))
  279. {
  280. return false;
  281. }
  282. value = *mCurBufferp;
  283. ++mCurBufferp;
  284. return true;
  285. }
  286. bool LLDataPackerBinaryBuffer::packU16(U16 value, const char* name)
  287. {
  288. if (!verifyLength(sizeof(U16), name))
  289. {
  290. return false;
  291. }
  292. if (mWriteEnabled)
  293. {
  294. htonmemcpy(mCurBufferp, &value, MVT_U16, 2);
  295. }
  296. mCurBufferp += 2;
  297. return true;
  298. }
  299. bool LLDataPackerBinaryBuffer::unpackU16(U16& value, const char* name)
  300. {
  301. if (!verifyLength(sizeof(U16), name))
  302. {
  303. return false;
  304. }
  305. htonmemcpy(&value, mCurBufferp, MVT_U16, 2);
  306. mCurBufferp += 2;
  307. return true;
  308. }
  309. bool LLDataPackerBinaryBuffer::packU32(U32 value, const char* name)
  310. {
  311. if (!verifyLength(sizeof(U32), name))
  312. {
  313. return false;
  314. }
  315. if (mWriteEnabled)
  316. {
  317. htonmemcpy(mCurBufferp, &value, MVT_U32, 4);
  318. }
  319. mCurBufferp += 4;
  320. return true;
  321. }
  322. bool LLDataPackerBinaryBuffer::unpackU32(U32& value, const char* name)
  323. {
  324. if (!verifyLength(sizeof(U32), name))
  325. {
  326. return false;
  327. }
  328. htonmemcpy(&value, mCurBufferp, MVT_U32, 4);
  329. mCurBufferp += 4;
  330. return true;
  331. }
  332. bool LLDataPackerBinaryBuffer::packS32(S32 value, const char* name)
  333. {
  334. if (!verifyLength(sizeof(S32), name))
  335. {
  336. return false;
  337. }
  338. if (mWriteEnabled)
  339. {
  340. htonmemcpy(mCurBufferp, &value, MVT_S32, 4);
  341. }
  342. mCurBufferp += 4;
  343. return true;
  344. }
  345. bool LLDataPackerBinaryBuffer::unpackS32(S32& value, const char* name)
  346. {
  347. if (!verifyLength(sizeof(S32), name))
  348. {
  349. return false;
  350. }
  351. htonmemcpy(&value, mCurBufferp, MVT_S32, 4);
  352. mCurBufferp += 4;
  353. return true;
  354. }
  355. bool LLDataPackerBinaryBuffer::packF32(F32 value, const char* name)
  356. {
  357. if (!verifyLength(sizeof(F32), name))
  358. {
  359. return false;
  360. }
  361. if (mWriteEnabled)
  362. {
  363. htonmemcpy(mCurBufferp, &value, MVT_F32, 4);
  364. }
  365. mCurBufferp += 4;
  366. return true;
  367. }
  368. bool LLDataPackerBinaryBuffer::unpackF32(F32& value, const char* name)
  369. {
  370. if (!verifyLength(sizeof(F32), name))
  371. {
  372. return false;
  373. }
  374. htonmemcpy(&value, mCurBufferp, MVT_F32, 4);
  375. mCurBufferp += 4;
  376. return true;
  377. }
  378. bool LLDataPackerBinaryBuffer::packColor4(const LLColor4& value,
  379. const char* name)
  380. {
  381. if (!verifyLength(16, name))
  382. {
  383. return false;
  384. }
  385. if (mWriteEnabled)
  386. {
  387. htonmemcpy(mCurBufferp, value.mV, MVT_LLVector4, 16);
  388. }
  389. mCurBufferp += 16;
  390. return true;
  391. }
  392. bool LLDataPackerBinaryBuffer::unpackColor4(LLColor4& value, const char* name)
  393. {
  394. if (!verifyLength(16, name))
  395. {
  396. return false;
  397. }
  398. htonmemcpy(value.mV, mCurBufferp, MVT_LLVector4, 16);
  399. mCurBufferp += 16;
  400. return true;
  401. }
  402. bool LLDataPackerBinaryBuffer::packColor4U(const LLColor4U& value,
  403. const char* name)
  404. {
  405. if (!verifyLength(4, name))
  406. {
  407. return false;
  408. }
  409. if (mWriteEnabled)
  410. {
  411. htonmemcpy(mCurBufferp, value.mV, MVT_VARIABLE, 4);
  412. }
  413. mCurBufferp += 4;
  414. return true;
  415. }
  416. bool LLDataPackerBinaryBuffer::unpackColor4U(LLColor4U& value,
  417. const char* name)
  418. {
  419. if (!verifyLength(4, name))
  420. {
  421. return false;
  422. }
  423. htonmemcpy(value.mV, mCurBufferp, MVT_VARIABLE, 4);
  424. mCurBufferp += 4;
  425. return true;
  426. }
  427. bool LLDataPackerBinaryBuffer::packVector2(const LLVector2& value,
  428. const char* name)
  429. {
  430. if (!verifyLength(8, name))
  431. {
  432. return false;
  433. }
  434. if (mWriteEnabled)
  435. {
  436. htonmemcpy(mCurBufferp, &value.mV[0], MVT_F32, 4);
  437. htonmemcpy(mCurBufferp + 4, &value.mV[1], MVT_F32, 4);
  438. }
  439. mCurBufferp += 8;
  440. return true;
  441. }
  442. bool LLDataPackerBinaryBuffer::unpackVector2(LLVector2& value,
  443. const char* name)
  444. {
  445. if (!verifyLength(8, name))
  446. {
  447. return false;
  448. }
  449. htonmemcpy(&value.mV[0], mCurBufferp, MVT_F32, 4);
  450. htonmemcpy(&value.mV[1], mCurBufferp + 4, MVT_F32, 4);
  451. mCurBufferp += 8;
  452. return true;
  453. }
  454. bool LLDataPackerBinaryBuffer::packVector3(const LLVector3& value,
  455. const char* name)
  456. {
  457. if (!verifyLength(12, name))
  458. {
  459. return false;
  460. }
  461. if (mWriteEnabled)
  462. {
  463. htonmemcpy(mCurBufferp, value.mV, MVT_LLVector3, 12);
  464. }
  465. mCurBufferp += 12;
  466. return true;
  467. }
  468. bool LLDataPackerBinaryBuffer::unpackVector3(LLVector3& value,
  469. const char* name)
  470. {
  471. if (!verifyLength(12, name))
  472. {
  473. return false;
  474. }
  475. htonmemcpy(value.mV, mCurBufferp, MVT_LLVector3, 12);
  476. mCurBufferp += 12;
  477. return true;
  478. }
  479. bool LLDataPackerBinaryBuffer::packVector4(const LLVector4& value,
  480. const char* name)
  481. {
  482. if (!verifyLength(16, name))
  483. {
  484. return false;
  485. }
  486. if (mWriteEnabled)
  487. {
  488. htonmemcpy(mCurBufferp, value.mV, MVT_LLVector4, 16);
  489. }
  490. mCurBufferp += 16;
  491. return true;
  492. }
  493. bool LLDataPackerBinaryBuffer::unpackVector4(LLVector4& value,
  494. const char* name)
  495. {
  496. if (!verifyLength(16, name))
  497. {
  498. return false;
  499. }
  500. htonmemcpy(value.mV, mCurBufferp, MVT_LLVector4, 16);
  501. mCurBufferp += 16;
  502. return true;
  503. }
  504. bool LLDataPackerBinaryBuffer::packUUID(const LLUUID& value, const char* name)
  505. {
  506. if (!verifyLength(16, name))
  507. {
  508. return false;
  509. }
  510. if (mWriteEnabled)
  511. {
  512. htonmemcpy(mCurBufferp, value.mData, MVT_LLUUID, 16);
  513. }
  514. mCurBufferp += 16;
  515. return true;
  516. }
  517. bool LLDataPackerBinaryBuffer::unpackUUID(LLUUID& value, const char* name)
  518. {
  519. if (!verifyLength(16, name))
  520. {
  521. return false;
  522. }
  523. htonmemcpy(value.mData, mCurBufferp, MVT_LLUUID, 16);
  524. mCurBufferp += 16;
  525. return true;
  526. }
  527. const LLDataPackerBinaryBuffer& LLDataPackerBinaryBuffer::operator=(const LLDataPackerBinaryBuffer& a)
  528. {
  529. if (a.getBufferSize() > getBufferSize())
  530. {
  531. // We have got problems, ack !
  532. llerrs << "Trying to do an assignment with not enough room in the target."
  533. << llendl;
  534. }
  535. memcpy(mBufferp, a.mBufferp, a.getBufferSize());
  536. return *this;
  537. }
  538. void LLDataPackerBinaryBuffer::dumpBufferToLog()
  539. {
  540. llwarns << "Binary Buffer Dump, size: " << mBufferSize << llendl;
  541. char line_buffer[256];
  542. S32 cur_line_pos = 0;
  543. S32 cur_line = 0;
  544. for (S32 i = 0; i < mBufferSize; ++i)
  545. {
  546. snprintf(line_buffer + cur_line_pos * 3,
  547. sizeof(line_buffer) - cur_line_pos * 3,
  548. "%02x ", mBufferp[i]);
  549. if (++cur_line_pos >= 16)
  550. {
  551. cur_line_pos = 0;
  552. llwarns << "Offset:" << std::hex << cur_line * 16 << std::dec
  553. << " Data:" << line_buffer << llendl;
  554. ++cur_line;
  555. }
  556. }
  557. if (cur_line_pos)
  558. {
  559. llwarns << "Offset:" << std::hex << cur_line * 16 << std::dec
  560. << " Data:" << line_buffer << llendl;
  561. }
  562. }
  563. //---------------------------------------------------------------------------
  564. // LLDataPackerAsciiBuffer implementation
  565. //---------------------------------------------------------------------------
  566. bool LLDataPackerAsciiBuffer::packString(const std::string& value,
  567. const char* name)
  568. {
  569. writeIndentedName(name);
  570. S32 numCopied = 0;
  571. if (mWriteEnabled)
  572. {
  573. numCopied = snprintf(mCurBufferp, getBufferSize() - getCurrentSize(),
  574. "%s\n", value.c_str());
  575. }
  576. else
  577. {
  578. numCopied = value.length() + 1;
  579. }
  580. // snprintf returns number of bytes that would have been written had the
  581. // output not being truncated. In that case, it will return either -1 or
  582. // value >= passed in size value . So a check needs to be added to detect
  583. // truncation, and if there is any, only account for the actual number of
  584. // bytes written..and not what could have been written.
  585. if (numCopied < 0 || numCopied > getBufferSize() - getCurrentSize())
  586. {
  587. // *NOTE: I believe we need to mark a failure bit at this point.
  588. numCopied = getBufferSize() - getCurrentSize();
  589. llwarns << "String truncated: " << value << llendl;
  590. }
  591. mCurBufferp += numCopied;
  592. return true;
  593. }
  594. bool LLDataPackerAsciiBuffer::unpackString(std::string& value,
  595. const char* name)
  596. {
  597. char valuestr[DP_BUFSIZE];
  598. if (getValueStr(name, valuestr, DP_BUFSIZE)) // NULL terminated
  599. {
  600. value = valuestr;
  601. return true;
  602. }
  603. else
  604. {
  605. return false;
  606. }
  607. }
  608. bool LLDataPackerAsciiBuffer::packBinaryData(const U8* value, S32 size,
  609. const char* name)
  610. {
  611. writeIndentedName(name);
  612. S32 numCopied = 0;
  613. if (mWriteEnabled)
  614. {
  615. numCopied = snprintf(mCurBufferp, getBufferSize() - getCurrentSize(),
  616. "%010d ", size);
  617. // snprintf returns number of bytes that would have been written had
  618. // the output not being truncated. In that case, it will return
  619. // >= passed in size value. So a check needs to be added to detect
  620. // truncation, and if there is any, only account for the actual number
  621. // of bytes written... and not what could have been written.
  622. if (numCopied < 0 || numCopied > getBufferSize() - getCurrentSize())
  623. {
  624. numCopied = getBufferSize() - getCurrentSize();
  625. llwarns << "Number truncated at size: " << size << llendl;
  626. }
  627. mCurBufferp += numCopied;
  628. bool buffer_full = false;
  629. for (S32 i = 0; i < size && !buffer_full; ++i)
  630. {
  631. numCopied = snprintf(mCurBufferp,
  632. getBufferSize() - getCurrentSize(), "%02x ",
  633. value[i]);
  634. if (numCopied < 0 ||
  635. numCopied > getBufferSize() - getCurrentSize())
  636. {
  637. numCopied = getBufferSize() - getCurrentSize();
  638. llwarns << "Data truncated" << llendl;
  639. buffer_full = true;
  640. }
  641. mCurBufferp += numCopied;
  642. }
  643. if (!buffer_full)
  644. {
  645. numCopied = snprintf(mCurBufferp,
  646. getBufferSize() - getCurrentSize(),
  647. "\n");
  648. if (numCopied < 0 ||
  649. numCopied > getBufferSize() - getCurrentSize())
  650. {
  651. numCopied = getBufferSize() - getCurrentSize();
  652. llwarns << "Newline truncated" << llendl;
  653. }
  654. mCurBufferp += numCopied;
  655. }
  656. }
  657. else
  658. {
  659. // why +10 ?? XXXCHECK
  660. numCopied = 10 + 1; // size plus newline
  661. numCopied += size;
  662. if (numCopied > getBufferSize() - getCurrentSize())
  663. {
  664. numCopied = getBufferSize() - getCurrentSize();
  665. }
  666. mCurBufferp += numCopied;
  667. }
  668. return true;
  669. }
  670. bool LLDataPackerAsciiBuffer::unpackBinaryData(U8* value, S32& size,
  671. const char* name)
  672. {
  673. char valuestr[DP_BUFSIZE];
  674. if (getValueStr(name, valuestr, DP_BUFSIZE))
  675. {
  676. char* cur_pos = &valuestr[0];
  677. sscanf(valuestr,"%010d", &size);
  678. cur_pos += 11;
  679. for (S32 i = 0; i < size; ++i)
  680. {
  681. S32 val;
  682. sscanf(cur_pos,"%02x", &val);
  683. value[i] = val;
  684. cur_pos += 3;
  685. }
  686. return true;
  687. }
  688. else
  689. {
  690. return false;
  691. }
  692. }
  693. bool LLDataPackerAsciiBuffer::packBinaryDataFixed(const U8* value, S32 size,
  694. const char* name)
  695. {
  696. writeIndentedName(name);
  697. if (mWriteEnabled)
  698. {
  699. S32 numCopied = 0;
  700. bool buffer_full = false;
  701. for (S32 i = 0; i < size && !buffer_full; ++i)
  702. {
  703. numCopied = snprintf(mCurBufferp, getBufferSize() - getCurrentSize(),
  704. "%02x ", value[i]);
  705. if (numCopied < 0 || numCopied > getBufferSize() - getCurrentSize())
  706. {
  707. numCopied = getBufferSize() - getCurrentSize();
  708. llwarns << "Data truncated" << llendl;
  709. buffer_full = true;
  710. }
  711. mCurBufferp += numCopied;
  712. }
  713. if (!buffer_full)
  714. {
  715. numCopied = snprintf(mCurBufferp,getBufferSize() - getCurrentSize(),
  716. "\n");
  717. if (numCopied < 0 || numCopied > getBufferSize() - getCurrentSize())
  718. {
  719. numCopied = getBufferSize() - getCurrentSize();
  720. llwarns << "Newline truncated" << llendl;
  721. }
  722. mCurBufferp += numCopied;
  723. }
  724. }
  725. else
  726. {
  727. S32 numCopied = 2 * size + 1; //hex bytes plus newline
  728. if (numCopied > getBufferSize() - getCurrentSize())
  729. {
  730. numCopied = getBufferSize() - getCurrentSize();
  731. }
  732. mCurBufferp += numCopied;
  733. }
  734. return true;
  735. }
  736. bool LLDataPackerAsciiBuffer::unpackBinaryDataFixed(U8* value, S32 size,
  737. const char* name)
  738. {
  739. char valuestr[DP_BUFSIZE];
  740. if (getValueStr(name, valuestr, DP_BUFSIZE))
  741. {
  742. char* cur_pos = &valuestr[0];
  743. for (S32 i = 0; i < size; ++i)
  744. {
  745. S32 val;
  746. sscanf(cur_pos,"%02x", &val);
  747. value[i] = val;
  748. cur_pos += 3;
  749. }
  750. return true;
  751. }
  752. else
  753. {
  754. return false;
  755. }
  756. }
  757. bool LLDataPackerAsciiBuffer::packU8(U8 value, const char* name)
  758. {
  759. writeIndentedName(name);
  760. S32 numCopied = 0;
  761. if (mWriteEnabled)
  762. {
  763. numCopied = snprintf(mCurBufferp, getBufferSize() - getCurrentSize(),
  764. "%d\n", value);
  765. }
  766. else
  767. {
  768. // just do the write to a temp buffer to get the length
  769. numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%d\n",
  770. value);
  771. }
  772. // snprintf returns number of bytes that would have been written had the
  773. // output not being truncated. In that case, it will return either -1 or
  774. // value >= passed in size value . So a check needs to be added to detect
  775. // truncation, and if there is any, only account for the actual number of
  776. // bytes written..and not what could have been written.
  777. if (numCopied < 0 || numCopied > getBufferSize() - getCurrentSize())
  778. {
  779. numCopied = getBufferSize() - getCurrentSize();
  780. llwarns << "U8truncated: " << value << llendl;
  781. }
  782. mCurBufferp += numCopied;
  783. return true;
  784. }
  785. bool LLDataPackerAsciiBuffer::unpackU8(U8 &value, const char* name)
  786. {
  787. char valuestr[DP_BUFSIZE];
  788. if (getValueStr(name, valuestr, DP_BUFSIZE))
  789. {
  790. S32 in_val;
  791. sscanf(valuestr,"%d", &in_val);
  792. value = in_val;
  793. return true;
  794. }
  795. else
  796. {
  797. return false;
  798. }
  799. }
  800. bool LLDataPackerAsciiBuffer::packU16(U16 value, const char* name)
  801. {
  802. writeIndentedName(name);
  803. S32 numCopied = 0;
  804. if (mWriteEnabled)
  805. {
  806. numCopied = snprintf(mCurBufferp, getBufferSize() - getCurrentSize(),
  807. "%d\n", value);
  808. }
  809. else
  810. {
  811. numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%d\n",
  812. value);
  813. }
  814. // snprintf returns number of bytes that would have been written had the
  815. // output not being truncated. In that case, it will return either -1 or
  816. // value >= passed in size value . So a check needs to be added to detect
  817. // truncation, and if there is any, only account for the actual number of
  818. // bytes written..and not what could have been written.
  819. if (numCopied < 0 || numCopied > getBufferSize() - getCurrentSize())
  820. {
  821. numCopied = getBufferSize() - getCurrentSize();
  822. llwarns << "U16 truncated: " << value << llendl;
  823. }
  824. mCurBufferp += numCopied;
  825. return true;
  826. }
  827. bool LLDataPackerAsciiBuffer::unpackU16(U16& value, const char* name)
  828. {
  829. char valuestr[DP_BUFSIZE];
  830. if (getValueStr(name, valuestr, DP_BUFSIZE))
  831. {
  832. S32 in_val;
  833. sscanf(valuestr,"%d", &in_val);
  834. value = in_val;
  835. return true;
  836. }
  837. else
  838. {
  839. return false;
  840. }
  841. }
  842. bool LLDataPackerAsciiBuffer::packU32(U32 value, const char* name)
  843. {
  844. writeIndentedName(name);
  845. S32 numCopied = 0;
  846. if (mWriteEnabled)
  847. {
  848. numCopied = snprintf(mCurBufferp, getBufferSize() - getCurrentSize(),
  849. "%u\n", value);
  850. }
  851. else
  852. {
  853. numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%u\n",
  854. value);
  855. }
  856. // snprintf returns number of bytes that would have been written had the
  857. // output not being truncated. In that case, it will return either -1 or
  858. // value >= passed in size value . So a check needs to be added to detect
  859. // truncation, and if there is any, only account for the actual number of
  860. // bytes written..and not what could have been written.
  861. if (numCopied < 0 || numCopied > getBufferSize() - getCurrentSize())
  862. {
  863. numCopied = getBufferSize() - getCurrentSize();
  864. llwarns << "U32 truncated: " << value << llendl;
  865. }
  866. mCurBufferp += numCopied;
  867. return true;
  868. }
  869. bool LLDataPackerAsciiBuffer::unpackU32(U32& value, const char* name)
  870. {
  871. char valuestr[DP_BUFSIZE];
  872. if (getValueStr(name, valuestr, DP_BUFSIZE))
  873. {
  874. sscanf(valuestr,"%u", &value);
  875. return true;
  876. }
  877. else
  878. {
  879. return false;
  880. }
  881. }
  882. bool LLDataPackerAsciiBuffer::packS32(S32 value, const char* name)
  883. {
  884. writeIndentedName(name);
  885. S32 numCopied = 0;
  886. if (mWriteEnabled)
  887. {
  888. numCopied = snprintf(mCurBufferp, getBufferSize() - getCurrentSize(),
  889. "%d\n", value);
  890. }
  891. else
  892. {
  893. numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%d\n",
  894. value);
  895. }
  896. // snprintf returns number of bytes that would have been written had the
  897. // output not being truncated. In that case, it will return either -1 or
  898. // value >= passed in size value . So a check needs to be added to detect
  899. // truncation, and if there is any, only account for the actual number of
  900. // bytes written..and not what could have been written.
  901. if (numCopied < 0 || numCopied > getBufferSize() - getCurrentSize())
  902. {
  903. numCopied = getBufferSize() - getCurrentSize();
  904. llwarns << "S32 truncated: " << value << llendl;
  905. }
  906. mCurBufferp += numCopied;
  907. return true;
  908. }
  909. bool LLDataPackerAsciiBuffer::unpackS32(S32& value, const char* name)
  910. {
  911. char valuestr[DP_BUFSIZE];
  912. if (getValueStr(name, valuestr, DP_BUFSIZE))
  913. {
  914. sscanf(valuestr,"%d", &value);
  915. return true;
  916. }
  917. else
  918. {
  919. return false;
  920. }
  921. }
  922. bool LLDataPackerAsciiBuffer::packF32(F32 value, const char* name)
  923. {
  924. writeIndentedName(name);
  925. S32 numCopied = 0;
  926. if (mWriteEnabled)
  927. {
  928. numCopied = snprintf(mCurBufferp, getBufferSize() - getCurrentSize(),
  929. "%f\n", value);
  930. }
  931. else
  932. {
  933. numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%f\n",
  934. value);
  935. }
  936. // snprintf returns number of bytes that would have been written had the
  937. // output not being truncated. In that case, it will return either -1 or
  938. // value >= passed in size value . So a check needs to be added to detect
  939. // truncation, and if there is any, only account for the actual number of
  940. // bytes written..and not what could have been written.
  941. if (numCopied < 0 || numCopied > getBufferSize() - getCurrentSize())
  942. {
  943. numCopied = getBufferSize() - getCurrentSize();
  944. llwarns << "F32 truncated: " << value << llendl;
  945. }
  946. mCurBufferp += numCopied;
  947. return true;
  948. }
  949. bool LLDataPackerAsciiBuffer::unpackF32(F32& value, const char* name)
  950. {
  951. char valuestr[DP_BUFSIZE];
  952. if (getValueStr(name, valuestr, DP_BUFSIZE))
  953. {
  954. sscanf(valuestr,"%f", &value);
  955. return true;
  956. }
  957. else
  958. {
  959. return false;
  960. }
  961. }
  962. bool LLDataPackerAsciiBuffer::packColor4(const LLColor4& value,
  963. const char* name)
  964. {
  965. writeIndentedName(name);
  966. S32 numCopied = 0;
  967. if (mWriteEnabled)
  968. {
  969. numCopied = snprintf(mCurBufferp, getBufferSize() - getCurrentSize(),
  970. "%f %f %f %f\n", value.mV[0], value.mV[1],
  971. value.mV[2], value.mV[3]);
  972. }
  973. else
  974. {
  975. numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER),
  976. "%f %f %f %f\n", value.mV[0], value.mV[1],
  977. value.mV[2], value.mV[3]);
  978. }
  979. // snprintf returns number of bytes that would have been written had the
  980. // output not being truncated. In that case, it will return either -1 or
  981. // value >= passed in size value . So a check needs to be added to detect
  982. // truncation, and if there is any, only account for the actual number of
  983. // bytes written..and not what could have been written.
  984. if (numCopied < 0 || numCopied > getBufferSize() - getCurrentSize())
  985. {
  986. numCopied = getBufferSize() - getCurrentSize();
  987. llwarns << "Color4: truncated: " << value << llendl;
  988. }
  989. mCurBufferp += numCopied;
  990. return true;
  991. }
  992. bool LLDataPackerAsciiBuffer::unpackColor4(LLColor4& value, const char* name)
  993. {
  994. char valuestr[DP_BUFSIZE];
  995. if (getValueStr(name, valuestr, DP_BUFSIZE))
  996. {
  997. sscanf(valuestr,"%f %f %f %f", &value.mV[0], &value.mV[1],
  998. &value.mV[2], &value.mV[3]);
  999. return true;
  1000. }
  1001. else
  1002. {
  1003. return false;
  1004. }
  1005. }
  1006. bool LLDataPackerAsciiBuffer::packColor4U(const LLColor4U& value,
  1007. const char* name)
  1008. {
  1009. writeIndentedName(name);
  1010. S32 numCopied = 0;
  1011. if (mWriteEnabled)
  1012. {
  1013. numCopied = snprintf(mCurBufferp, getBufferSize() - getCurrentSize(),
  1014. "%d %d %d %d\n", value.mV[0], value.mV[1],
  1015. value.mV[2], value.mV[3]);
  1016. }
  1017. else
  1018. {
  1019. numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER),
  1020. "%d %d %d %d\n", value.mV[0], value.mV[1],
  1021. value.mV[2], value.mV[3]);
  1022. }
  1023. // snprintf returns number of bytes that would have been written had the
  1024. // output not being truncated. In that case, it will return either -1 or
  1025. // value >= passed in size value . So a check needs to be added to detect
  1026. // truncation, and if there is any, only account for the actual number of
  1027. // bytes written..and not what could have been written.
  1028. if (numCopied < 0 || numCopied > getBufferSize() - getCurrentSize())
  1029. {
  1030. numCopied = getBufferSize() - getCurrentSize();
  1031. llwarns << "Color4U truncated: " << value << llendl;
  1032. }
  1033. mCurBufferp += numCopied;
  1034. return true;
  1035. }
  1036. bool LLDataPackerAsciiBuffer::unpackColor4U(LLColor4U& value, const char* name)
  1037. {
  1038. char valuestr[DP_BUFSIZE];
  1039. if (getValueStr(name, valuestr, DP_BUFSIZE))
  1040. {
  1041. S32 r, g, b, a;
  1042. sscanf(valuestr,"%d %d %d %d", &r, &g, &b, &a);
  1043. value.mV[0] = r;
  1044. value.mV[1] = g;
  1045. value.mV[2] = b;
  1046. value.mV[3] = a;
  1047. return true;
  1048. }
  1049. else
  1050. {
  1051. return false;
  1052. }
  1053. }
  1054. bool LLDataPackerAsciiBuffer::packVector2(const LLVector2& value,
  1055. const char* name)
  1056. {
  1057. writeIndentedName(name);
  1058. S32 numCopied = 0;
  1059. if (mWriteEnabled)
  1060. {
  1061. numCopied = snprintf(mCurBufferp, getBufferSize() - getCurrentSize(),
  1062. "%f %f\n", value.mV[0], value.mV[1]);
  1063. }
  1064. else
  1065. {
  1066. numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%f %f\n",
  1067. value.mV[0], value.mV[1]);
  1068. }
  1069. // snprintf returns number of bytes that would have been written had the
  1070. // output not being truncated. In that case, it will return either -1 or
  1071. // value >= passed in size value . So a check needs to be added to detect
  1072. // truncation, and if there is any, only account for the actual number of
  1073. // bytes written..and not what could have been written.
  1074. if (numCopied < 0 || numCopied > getBufferSize() - getCurrentSize())
  1075. {
  1076. numCopied = getBufferSize() - getCurrentSize();
  1077. llwarns << "Vector2 truncated: " << value << llendl;
  1078. }
  1079. mCurBufferp += numCopied;
  1080. return true;
  1081. }
  1082. bool LLDataPackerAsciiBuffer::unpackVector2(LLVector2& value, const char* name)
  1083. {
  1084. char valuestr[DP_BUFSIZE];
  1085. if (getValueStr(name, valuestr, DP_BUFSIZE))
  1086. {
  1087. sscanf(valuestr,"%f %f", &value.mV[0], &value.mV[1]);
  1088. return true;
  1089. }
  1090. else
  1091. {
  1092. return false;
  1093. }
  1094. }
  1095. bool LLDataPackerAsciiBuffer::packVector3(const LLVector3& value,
  1096. const char* name)
  1097. {
  1098. writeIndentedName(name);
  1099. S32 numCopied = 0;
  1100. if (mWriteEnabled)
  1101. {
  1102. numCopied = snprintf(mCurBufferp, getBufferSize() - getCurrentSize(),
  1103. "%f %f %f\n", value.mV[0], value.mV[1],
  1104. value.mV[2]);
  1105. }
  1106. else
  1107. {
  1108. numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%f %f %f\n",
  1109. value.mV[0], value.mV[1], value.mV[2]);
  1110. }
  1111. // snprintf returns number of bytes that would have been written had the
  1112. // output not being truncated. In that case, it will return either -1 or
  1113. // value >= passed in size value . So a check needs to be added to detect
  1114. // truncation, and if there is any, only account for the actual number of
  1115. // bytes written..and not what could have been written.
  1116. if (numCopied < 0 || numCopied > getBufferSize() - getCurrentSize())
  1117. {
  1118. numCopied = getBufferSize() - getCurrentSize();
  1119. llwarns << "Vector3 truncated: " << value << llendl;
  1120. }
  1121. mCurBufferp += numCopied;
  1122. return true;
  1123. }
  1124. bool LLDataPackerAsciiBuffer::unpackVector3(LLVector3& value, const char* name)
  1125. {
  1126. char valuestr[DP_BUFSIZE];
  1127. if (getValueStr(name, valuestr, DP_BUFSIZE))
  1128. {
  1129. sscanf(valuestr,"%f %f %f", &value.mV[0], &value.mV[1], &value.mV[2]);
  1130. return true;
  1131. }
  1132. else
  1133. {
  1134. return false;
  1135. }
  1136. }
  1137. bool LLDataPackerAsciiBuffer::packVector4(const LLVector4& value,
  1138. const char* name)
  1139. {
  1140. writeIndentedName(name);
  1141. S32 numCopied = 0;
  1142. if (mWriteEnabled)
  1143. {
  1144. numCopied = snprintf(mCurBufferp, getBufferSize() - getCurrentSize(),
  1145. "%f %f %f %f\n", value.mV[0], value.mV[1],
  1146. value.mV[2], value.mV[3]);
  1147. }
  1148. else
  1149. {
  1150. numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER),
  1151. "%f %f %f %f\n", value.mV[0], value.mV[1],
  1152. value.mV[2], value.mV[3]);
  1153. }
  1154. // snprintf returns number of bytes that would have been written had the
  1155. // output not being truncated. In that case, it will return either -1 or
  1156. // value >= passed in size value . So a check needs to be added to detect
  1157. // truncation, and if there is any, only account for the actual number of
  1158. // bytes written..and not what could have been written.
  1159. if (numCopied < 0 || numCopied > getBufferSize() - getCurrentSize())
  1160. {
  1161. numCopied = getBufferSize() - getCurrentSize();
  1162. llwarns << "Vector4 truncated: " << value << llendl;
  1163. }
  1164. mCurBufferp += numCopied;
  1165. return true;
  1166. }
  1167. bool LLDataPackerAsciiBuffer::unpackVector4(LLVector4& value, const char* name)
  1168. {
  1169. char valuestr[DP_BUFSIZE];
  1170. if (getValueStr(name, valuestr, DP_BUFSIZE))
  1171. {
  1172. sscanf(valuestr,"%f %f %f %f", &value.mV[0], &value.mV[1],
  1173. &value.mV[2], &value.mV[3]);
  1174. return true;
  1175. }
  1176. else
  1177. {
  1178. return false;
  1179. }
  1180. }
  1181. bool LLDataPackerAsciiBuffer::packUUID(const LLUUID& value, const char* name)
  1182. {
  1183. bool success = true;
  1184. writeIndentedName(name);
  1185. S32 numCopied = 0;
  1186. if (mWriteEnabled)
  1187. {
  1188. std::string tmp_str;
  1189. value.toString(tmp_str);
  1190. numCopied = snprintf(mCurBufferp, getBufferSize() - getCurrentSize(),
  1191. "%s\n", tmp_str.c_str());
  1192. }
  1193. else
  1194. {
  1195. numCopied = 64 + 1; // UUID + newline
  1196. }
  1197. // snprintf returns number of bytes that would have been written had the
  1198. // output not being truncated. In that case, it will return either -1 or
  1199. // value >= passed in size value . So a check needs to be added to detect
  1200. // truncation, and if there is any, only account for the actual number of
  1201. // bytes written..and not what could have been written.
  1202. if (numCopied < 0 || numCopied > getBufferSize() - getCurrentSize())
  1203. {
  1204. numCopied = getBufferSize() - getCurrentSize();
  1205. llwarns << "UUID truncated: " << value << llendl;
  1206. success = false;
  1207. }
  1208. mCurBufferp += numCopied;
  1209. return success;
  1210. }
  1211. bool LLDataPackerAsciiBuffer::unpackUUID(LLUUID& value, const char* name)
  1212. {
  1213. char valuestr[DP_BUFSIZE];
  1214. if (getValueStr(name, valuestr, DP_BUFSIZE))
  1215. {
  1216. char tmp_str[64];
  1217. sscanf(valuestr, "%63s", tmp_str);
  1218. value.set(tmp_str);
  1219. return true;
  1220. }
  1221. else
  1222. {
  1223. return false;
  1224. }
  1225. }
  1226. void LLDataPackerAsciiBuffer::dump()
  1227. {
  1228. llinfos << "Buffer: " << mBufferp << llendl;
  1229. }
  1230. void LLDataPackerAsciiBuffer::writeIndentedName(const char* name)
  1231. {
  1232. if (mIncludeNames)
  1233. {
  1234. S32 numCopied = 0;
  1235. if (mWriteEnabled)
  1236. {
  1237. numCopied = snprintf(mCurBufferp,
  1238. getBufferSize() - getCurrentSize(),
  1239. "%s\t", name);
  1240. }
  1241. else
  1242. {
  1243. // name + tab
  1244. numCopied = (S32)strlen(name) + 1;
  1245. }
  1246. // snprintf returns number of bytes that would have been written had
  1247. // the output not being truncated. In that case, it will return either
  1248. // -1 or value >= passed in size value . So a check needs to be added
  1249. // to detect truncation, and if there is any, only account for the
  1250. // actual number of bytes written..and not what could have been
  1251. // written.
  1252. if (numCopied < 0 || numCopied > getBufferSize() - getCurrentSize())
  1253. {
  1254. numCopied = getBufferSize() - getCurrentSize();
  1255. llwarns << "Name truncated: " << name << llendl;
  1256. }
  1257. mCurBufferp += numCopied;
  1258. }
  1259. }
  1260. bool LLDataPackerAsciiBuffer::getValueStr(const char* name, char* out_value,
  1261. S32 value_len)
  1262. {
  1263. char buffer[DP_BUFSIZE];
  1264. char keyword[DP_BUFSIZE];
  1265. char value[DP_BUFSIZE];
  1266. buffer[0] = '\0';
  1267. keyword[0] = '\0';
  1268. value[0] = '\0';
  1269. if (mIncludeNames)
  1270. {
  1271. // Read both the name and the value, and validate the name.
  1272. sscanf(mCurBufferp, "%511[^\n]", buffer);
  1273. // Skip the \n
  1274. mCurBufferp += (S32)strlen(buffer) + 1;
  1275. sscanf(buffer, "%511s %511[^\n]", keyword, value);
  1276. if (strcmp(keyword, name))
  1277. {
  1278. llwarns << "Data packer expecting keyword of type " << name
  1279. << ", got " << keyword << " instead !" << llendl;
  1280. return false;
  1281. }
  1282. }
  1283. else
  1284. {
  1285. // Just the value exists
  1286. sscanf(mCurBufferp, "%511[^\n]", value);
  1287. // Skip the \n
  1288. mCurBufferp += (S32)strlen(value) + 1;
  1289. }
  1290. S32 in_value_len = (S32)strlen(value) + 1;
  1291. S32 min_len = llmin(in_value_len, value_len);
  1292. memcpy(out_value, value, min_len);
  1293. out_value[min_len-1] = 0;
  1294. return true;
  1295. }
  1296. // helper function used by LLDataPackerAsciiFile to convert F32 into a string.
  1297. // This is to avoid << operator writing F32 value into a stream since it does
  1298. // not seem to preserve the float value
  1299. std::string convertF32ToString(F32 val)
  1300. {
  1301. std::string str;
  1302. char buf[20];
  1303. snprintf(buf, 20, "%f", val);
  1304. str = buf;
  1305. return str;
  1306. }
  1307. //---------------------------------------------------------------------------
  1308. // LLDataPackerAsciiFile implementation
  1309. //---------------------------------------------------------------------------
  1310. bool LLDataPackerAsciiFile::packString(const std::string& value,
  1311. const char* name)
  1312. {
  1313. writeIndentedName(name);
  1314. if (mFP)
  1315. {
  1316. fprintf(mFP,"%s\n", value.c_str());
  1317. }
  1318. else if (mOutputStream)
  1319. {
  1320. *mOutputStream << value << "\n";
  1321. }
  1322. return true;
  1323. }
  1324. bool LLDataPackerAsciiFile::unpackString(std::string& value, const char* name)
  1325. {
  1326. char valuestr[DP_BUFSIZE];
  1327. if (getValueStr(name, valuestr, DP_BUFSIZE))
  1328. {
  1329. value = valuestr;
  1330. return true;
  1331. }
  1332. else
  1333. {
  1334. return false;
  1335. }
  1336. }
  1337. bool LLDataPackerAsciiFile::packBinaryData(const U8* value, S32 size,
  1338. const char* name)
  1339. {
  1340. writeIndentedName(name);
  1341. if (mFP)
  1342. {
  1343. fprintf(mFP, "%010d ", size);
  1344. for (S32 i = 0; i < size; ++i)
  1345. {
  1346. fprintf(mFP, "%02x ", value[i]);
  1347. }
  1348. fprintf(mFP, "\n");
  1349. }
  1350. else if (mOutputStream)
  1351. {
  1352. char buffer[32];
  1353. snprintf(buffer,sizeof(buffer), "%010d ", size);
  1354. *mOutputStream << buffer;
  1355. for (S32 i = 0; i < size; ++i)
  1356. {
  1357. snprintf(buffer, sizeof(buffer), "%02x ", value[i]);
  1358. *mOutputStream << buffer;
  1359. }
  1360. *mOutputStream << "\n";
  1361. }
  1362. return true;
  1363. }
  1364. bool LLDataPackerAsciiFile::unpackBinaryData(U8* value, S32& size,
  1365. const char* name)
  1366. {
  1367. char valuestr[DP_BUFSIZE];
  1368. if (getValueStr(name, valuestr, DP_BUFSIZE))
  1369. {
  1370. char* cur_pos = &valuestr[0];
  1371. sscanf(valuestr,"%010d", &size);
  1372. cur_pos += 11;
  1373. for (S32 i = 0; i < size; ++i)
  1374. {
  1375. S32 val;
  1376. sscanf(cur_pos,"%02x", &val);
  1377. value[i] = val;
  1378. cur_pos += 3;
  1379. }
  1380. return true;
  1381. }
  1382. else
  1383. {
  1384. return false;
  1385. }
  1386. }
  1387. bool LLDataPackerAsciiFile::packBinaryDataFixed(const U8* value, S32 size,
  1388. const char* name)
  1389. {
  1390. writeIndentedName(name);
  1391. if (mFP)
  1392. {
  1393. for (S32 i = 0; i < size; ++i)
  1394. {
  1395. fprintf(mFP, "%02x ", value[i]);
  1396. }
  1397. fprintf(mFP, "\n");
  1398. }
  1399. else if (mOutputStream)
  1400. {
  1401. char buffer[32];
  1402. for (S32 i = 0; i < size; ++i)
  1403. {
  1404. snprintf(buffer, sizeof(buffer), "%02x ", value[i]);
  1405. *mOutputStream << buffer;
  1406. }
  1407. *mOutputStream << "\n";
  1408. }
  1409. return true;
  1410. }
  1411. bool LLDataPackerAsciiFile::unpackBinaryDataFixed(U8* value, S32 size,
  1412. const char* name)
  1413. {
  1414. char valuestr[DP_BUFSIZE];
  1415. if (getValueStr(name, valuestr, DP_BUFSIZE))
  1416. {
  1417. char *cur_pos = &valuestr[0];
  1418. for (S32 i = 0; i < size; ++i)
  1419. {
  1420. S32 val;
  1421. sscanf(cur_pos,"%02x", &val);
  1422. value[i] = val;
  1423. cur_pos += 3;
  1424. }
  1425. return true;
  1426. }
  1427. else
  1428. {
  1429. return false;
  1430. }
  1431. }
  1432. bool LLDataPackerAsciiFile::packU8(U8 value, const char* name)
  1433. {
  1434. writeIndentedName(name);
  1435. if (mFP)
  1436. {
  1437. fprintf(mFP,"%d\n", value);
  1438. }
  1439. else if (mOutputStream)
  1440. {
  1441. // We have to cast this to an integer because streams serialize bytes
  1442. // as bytes - not as text.
  1443. *mOutputStream << (S32)value << "\n";
  1444. }
  1445. return true;
  1446. }
  1447. bool LLDataPackerAsciiFile::unpackU8(U8 &value, const char* name)
  1448. {
  1449. char valuestr[DP_BUFSIZE];
  1450. if (getValueStr(name, valuestr, DP_BUFSIZE))
  1451. {
  1452. S32 in_val;
  1453. sscanf(valuestr,"%d", &in_val);
  1454. value = in_val;
  1455. return true;
  1456. }
  1457. else
  1458. {
  1459. return false;
  1460. }
  1461. }
  1462. bool LLDataPackerAsciiFile::packU16(U16 value, const char* name)
  1463. {
  1464. writeIndentedName(name);
  1465. if (mFP)
  1466. {
  1467. fprintf(mFP,"%d\n", value);
  1468. }
  1469. else if (mOutputStream)
  1470. {
  1471. *mOutputStream <<"" << value << "\n";
  1472. }
  1473. return true;
  1474. }
  1475. bool LLDataPackerAsciiFile::unpackU16(U16& value, const char* name)
  1476. {
  1477. char valuestr[DP_BUFSIZE];
  1478. if (getValueStr(name, valuestr, DP_BUFSIZE))
  1479. {
  1480. S32 in_val;
  1481. sscanf(valuestr,"%d", &in_val);
  1482. value = in_val;
  1483. return true;
  1484. }
  1485. else
  1486. {
  1487. return false;
  1488. }
  1489. }
  1490. bool LLDataPackerAsciiFile::packU32(U32 value, const char* name)
  1491. {
  1492. writeIndentedName(name);
  1493. if (mFP)
  1494. {
  1495. fprintf(mFP,"%u\n", value);
  1496. }
  1497. else if (mOutputStream)
  1498. {
  1499. *mOutputStream <<"" << value << "\n";
  1500. }
  1501. return true;
  1502. }
  1503. bool LLDataPackerAsciiFile::unpackU32(U32& value, const char* name)
  1504. {
  1505. char valuestr[DP_BUFSIZE];
  1506. if (getValueStr(name, valuestr, DP_BUFSIZE))
  1507. {
  1508. sscanf(valuestr,"%u", &value);
  1509. return true;
  1510. }
  1511. else
  1512. {
  1513. return false;
  1514. }
  1515. }
  1516. bool LLDataPackerAsciiFile::packS32(S32 value, const char* name)
  1517. {
  1518. writeIndentedName(name);
  1519. if (mFP)
  1520. {
  1521. fprintf(mFP,"%d\n", value);
  1522. }
  1523. else if (mOutputStream)
  1524. {
  1525. *mOutputStream <<"" << value << "\n";
  1526. }
  1527. return true;
  1528. }
  1529. bool LLDataPackerAsciiFile::unpackS32(S32& value, const char* name)
  1530. {
  1531. char valuestr[DP_BUFSIZE];
  1532. if (getValueStr(name, valuestr, DP_BUFSIZE))
  1533. {
  1534. sscanf(valuestr,"%d", &value);
  1535. return true;
  1536. }
  1537. else
  1538. {
  1539. return false;
  1540. }
  1541. }
  1542. bool LLDataPackerAsciiFile::packF32(F32 value, const char* name)
  1543. {
  1544. writeIndentedName(name);
  1545. if (mFP)
  1546. {
  1547. fprintf(mFP,"%f\n", value);
  1548. }
  1549. else if (mOutputStream)
  1550. {
  1551. *mOutputStream <<"" << convertF32ToString(value) << "\n";
  1552. }
  1553. return true;
  1554. }
  1555. bool LLDataPackerAsciiFile::unpackF32(F32& value, const char* name)
  1556. {
  1557. char valuestr[DP_BUFSIZE];
  1558. if (getValueStr(name, valuestr, DP_BUFSIZE))
  1559. {
  1560. sscanf(valuestr,"%f", &value);
  1561. return true;
  1562. }
  1563. else
  1564. {
  1565. return false;
  1566. }
  1567. }
  1568. bool LLDataPackerAsciiFile::packColor4(const LLColor4& value, const char* name)
  1569. {
  1570. writeIndentedName(name);
  1571. if (mFP)
  1572. {
  1573. fprintf(mFP,"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2],
  1574. value.mV[3]);
  1575. }
  1576. else if (mOutputStream)
  1577. {
  1578. *mOutputStream << convertF32ToString(value.mV[0]) << " "
  1579. << convertF32ToString(value.mV[1]) << " "
  1580. << convertF32ToString(value.mV[2]) << " "
  1581. << convertF32ToString(value.mV[3]) << "\n";
  1582. }
  1583. return true;
  1584. }
  1585. bool LLDataPackerAsciiFile::unpackColor4(LLColor4& value, const char* name)
  1586. {
  1587. char valuestr[DP_BUFSIZE];
  1588. if (getValueStr(name, valuestr, DP_BUFSIZE))
  1589. {
  1590. sscanf(valuestr,"%f %f %f %f", &value.mV[0], &value.mV[1],
  1591. &value.mV[2], &value.mV[3]);
  1592. return true;
  1593. }
  1594. else
  1595. {
  1596. return false;
  1597. }
  1598. }
  1599. bool LLDataPackerAsciiFile::packColor4U(const LLColor4U& value,
  1600. const char* name)
  1601. {
  1602. writeIndentedName(name);
  1603. if (mFP)
  1604. {
  1605. fprintf(mFP,"%d %d %d %d\n", value.mV[0], value.mV[1], value.mV[2],
  1606. value.mV[3]);
  1607. }
  1608. else if (mOutputStream)
  1609. {
  1610. *mOutputStream << (S32)(value.mV[0]) << " "
  1611. << (S32)(value.mV[1]) << " "
  1612. << (S32)(value.mV[2]) << " "
  1613. << (S32)(value.mV[3]) << "\n";
  1614. }
  1615. return true;
  1616. }
  1617. bool LLDataPackerAsciiFile::unpackColor4U(LLColor4U& value, const char* name)
  1618. {
  1619. char valuestr[DP_BUFSIZE];
  1620. if (getValueStr(name, valuestr, DP_BUFSIZE))
  1621. {
  1622. S32 r, g, b, a;
  1623. sscanf(valuestr,"%d %d %d %d", &r, &g, &b, &a);
  1624. value.mV[0] = r;
  1625. value.mV[1] = g;
  1626. value.mV[2] = b;
  1627. value.mV[3] = a;
  1628. return true;
  1629. }
  1630. else
  1631. {
  1632. return false;
  1633. }
  1634. }
  1635. bool LLDataPackerAsciiFile::packVector2(const LLVector2& value,
  1636. const char* name)
  1637. {
  1638. writeIndentedName(name);
  1639. if (mFP)
  1640. {
  1641. fprintf(mFP,"%f %f\n", value.mV[0], value.mV[1]);
  1642. }
  1643. else if (mOutputStream)
  1644. {
  1645. *mOutputStream << convertF32ToString(value.mV[0]) << " "
  1646. << convertF32ToString(value.mV[1]) << "\n";
  1647. }
  1648. return true;
  1649. }
  1650. bool LLDataPackerAsciiFile::unpackVector2(LLVector2& value, const char* name)
  1651. {
  1652. char valuestr[DP_BUFSIZE];
  1653. if (getValueStr(name, valuestr, DP_BUFSIZE))
  1654. {
  1655. sscanf(valuestr,"%f %f", &value.mV[0], &value.mV[1]);
  1656. return true;
  1657. }
  1658. else
  1659. {
  1660. return false;
  1661. }
  1662. }
  1663. bool LLDataPackerAsciiFile::packVector3(const LLVector3& value,
  1664. const char* name)
  1665. {
  1666. writeIndentedName(name);
  1667. if (mFP)
  1668. {
  1669. fprintf(mFP,"%f %f %f\n", value.mV[0], value.mV[1], value.mV[2]);
  1670. }
  1671. else if (mOutputStream)
  1672. {
  1673. *mOutputStream << convertF32ToString(value.mV[0]) << " "
  1674. << convertF32ToString(value.mV[1]) << " "
  1675. << convertF32ToString(value.mV[2]) << "\n";
  1676. }
  1677. return true;
  1678. }
  1679. bool LLDataPackerAsciiFile::unpackVector3(LLVector3& value, const char* name)
  1680. {
  1681. char valuestr[DP_BUFSIZE];
  1682. if (getValueStr(name, valuestr, DP_BUFSIZE))
  1683. {
  1684. sscanf(valuestr,"%f %f %f", &value.mV[0], &value.mV[1], &value.mV[2]);
  1685. return true;
  1686. }
  1687. else
  1688. {
  1689. return false;
  1690. }
  1691. }
  1692. bool LLDataPackerAsciiFile::packVector4(const LLVector4& value,
  1693. const char* name)
  1694. {
  1695. writeIndentedName(name);
  1696. if (mFP)
  1697. {
  1698. fprintf(mFP,"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2],
  1699. value.mV[3]);
  1700. }
  1701. else if (mOutputStream)
  1702. {
  1703. *mOutputStream << convertF32ToString(value.mV[0]) << " "
  1704. << convertF32ToString(value.mV[1]) << " "
  1705. << convertF32ToString(value.mV[2]) << " "
  1706. << convertF32ToString(value.mV[3]) << "\n";
  1707. }
  1708. return true;
  1709. }
  1710. bool LLDataPackerAsciiFile::unpackVector4(LLVector4& value, const char* name)
  1711. {
  1712. char valuestr[DP_BUFSIZE];
  1713. if (getValueStr(name, valuestr, DP_BUFSIZE))
  1714. {
  1715. sscanf(valuestr,"%f %f %f %f", &value.mV[0], &value.mV[1],
  1716. &value.mV[2], &value.mV[3]);
  1717. return true;
  1718. }
  1719. else
  1720. {
  1721. return false;
  1722. }
  1723. }
  1724. bool LLDataPackerAsciiFile::packUUID(const LLUUID& value, const char* name)
  1725. {
  1726. writeIndentedName(name);
  1727. std::string tmp_str;
  1728. value.toString(tmp_str);
  1729. if (mFP)
  1730. {
  1731. fprintf(mFP,"%s\n", tmp_str.c_str());
  1732. }
  1733. else if (mOutputStream)
  1734. {
  1735. *mOutputStream <<"" << tmp_str << "\n";
  1736. }
  1737. return true;
  1738. }
  1739. bool LLDataPackerAsciiFile::unpackUUID(LLUUID& value, const char* name)
  1740. {
  1741. char valuestr[DP_BUFSIZE];
  1742. if (getValueStr(name, valuestr, DP_BUFSIZE))
  1743. {
  1744. char tmp_str[64];
  1745. sscanf(valuestr,"%63s",tmp_str);
  1746. value.set(tmp_str);
  1747. return true;
  1748. }
  1749. else
  1750. {
  1751. return false;
  1752. }
  1753. }
  1754. void LLDataPackerAsciiFile::writeIndentedName(const char* name)
  1755. {
  1756. std::string indent_buf;
  1757. indent_buf.reserve(mIndent + 1);
  1758. S32 i;
  1759. for (i = 0; i < mIndent; ++i)
  1760. {
  1761. indent_buf[i] = '\t';
  1762. }
  1763. indent_buf[i] = 0;
  1764. if (mFP)
  1765. {
  1766. fprintf(mFP,"%s%s\t",indent_buf.c_str(), name);
  1767. }
  1768. else if (mOutputStream)
  1769. {
  1770. *mOutputStream << indent_buf << name << "\t";
  1771. }
  1772. }
  1773. bool LLDataPackerAsciiFile::getValueStr(const char* name, char* out_value,
  1774. S32 value_len)
  1775. {
  1776. bool success = false;
  1777. char buffer[DP_BUFSIZE];
  1778. char keyword[DP_BUFSIZE];
  1779. char value[DP_BUFSIZE];
  1780. buffer[0] = '\0';
  1781. keyword[0] = '\0';
  1782. value[0] = '\0';
  1783. if (mFP)
  1784. {
  1785. fpos_t last_pos;
  1786. if (fgetpos(mFP, &last_pos) != 0) // 0==success for fgetpos
  1787. {
  1788. llwarns << "Data packer failed to fgetpos" << llendl;
  1789. return false;
  1790. }
  1791. if (fgets(buffer, DP_BUFSIZE, mFP) == NULL)
  1792. {
  1793. buffer[0] = '\0';
  1794. }
  1795. sscanf(buffer, "%511s %511[^\n]", keyword, value);
  1796. if (!keyword[0])
  1797. {
  1798. llwarns << "Data packer could not get the keyword !" << llendl;
  1799. fsetpos(mFP, &last_pos);
  1800. return false;
  1801. }
  1802. if (strcmp(keyword, name))
  1803. {
  1804. llwarns << "Data packer expecting keyword of type " << name
  1805. << ", got " << keyword << " instead !" << llendl;
  1806. fsetpos(mFP, &last_pos);
  1807. return false;
  1808. }
  1809. S32 in_value_len = (S32)strlen(value) + 1;
  1810. S32 min_len = llmin(in_value_len, value_len);
  1811. memcpy(out_value, value, min_len);
  1812. out_value[min_len - 1] = 0;
  1813. success = true;
  1814. }
  1815. else if (mInputStream)
  1816. {
  1817. mInputStream->getline(buffer, DP_BUFSIZE);
  1818. sscanf(buffer, "%511s %511[^\n]", keyword, value);
  1819. if (!keyword[0])
  1820. {
  1821. llwarns << "Data packer could not get the keyword !" << llendl;
  1822. return false;
  1823. }
  1824. if (strcmp(keyword, name))
  1825. {
  1826. llwarns << "Data packer expecting keyword of type " << name
  1827. << ", got " << keyword << " instead !" << llendl;
  1828. return false;
  1829. }
  1830. S32 in_value_len = (S32)strlen(value) + 1;
  1831. S32 min_len = llmin(in_value_len, value_len);
  1832. memcpy(out_value, value, min_len);
  1833. out_value[min_len - 1] = 0;
  1834. success = true;
  1835. }
  1836. return success;
  1837. }