cProtoBufUtils.pas 57 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988
  1. {******************************************************************************}
  2. { }
  3. { Library: Fundamentals 4.00 }
  4. { File name: cProtoBufUtils.pas }
  5. { File version: 0.03 }
  6. { Description: Protocol Buffer utilities. }
  7. { }
  8. { Copyright: Copyright (c) 2012-2013, David J Butler }
  9. { All rights reserved. }
  10. { This file is licensed under the BSD License. }
  11. { See http://www.opensource.org/licenses/bsd-license.php }
  12. { Redistribution and use in source and binary forms, with }
  13. { or without modification, are permitted provided that }
  14. { the following conditions are met: }
  15. { Redistributions of source code must retain the above }
  16. { copyright notice, this list of conditions and the }
  17. { following disclaimer. }
  18. { THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND }
  19. { CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED }
  20. { WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED }
  21. { WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A }
  22. { PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL }
  23. { THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, }
  24. { INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR }
  25. { CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, }
  26. { PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF }
  27. { USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) }
  28. { HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER }
  29. { IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING }
  30. { NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE }
  31. { USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE }
  32. { POSSIBILITY OF SUCH DAMAGE. }
  33. { }
  34. { Home page: http://fundementals.sourceforge.net }
  35. { Forum: http://sourceforge.net/forum/forum.php?forum_id=2117 }
  36. { E-mail: fundamentals.library@gmail.com }
  37. { }
  38. { Revision history: }
  39. { }
  40. { 2012/04/14 0.01 VarInt encoding and decoding }
  41. { 2012/04/15 0.02 SInt32 encoding and decoding }
  42. { 2012/04/25 0.03 Improvements }
  43. { }
  44. {******************************************************************************}
  45. {$INCLUDE cProtoBuf.inc}
  46. unit cProtoBufUtils;
  47. interface
  48. uses
  49. { System }
  50. SysUtils,
  51. { Fundamentals }
  52. cUtils;
  53. { SInt32 / SInt64 }
  54. function pbSInt32ToUInt32(const A: LongInt): LongWord;
  55. function pbUInt32ToSInt32(const A: LongWord): LongInt;
  56. function pbSInt64ToUInt64(const A: Int64): UInt64;
  57. function pbUInt64ToSInt64(const A: UInt64): Int64;
  58. { VarInt }
  59. const
  60. pbMaxVarIntSizeEnc = 10;
  61. type
  62. EpbVarIntError = class(Exception);
  63. TpbVarInt = record
  64. EncSize : Byte;
  65. EncData : array[0..pbMaxVarIntSizeEnc - 1] of Byte;
  66. end;
  67. function pbVarIntEquals(const A, B: TpbVarInt): Boolean;
  68. function pbVarIntIsZero(var A: TpbVarInt): Boolean;
  69. procedure pbVarIntInitZero(var A: TpbVarInt);
  70. procedure pbVarIntInitVarInt(var A: TpbVarInt; const B: TpbVarInt);
  71. function pbVarIntInitEncBuf(var A: TpbVarInt; const Buf; const BufSize: Integer): Integer;
  72. procedure pbVarIntInitBinBuf(var A: TpbVarInt; const Buf; const BufSize: Integer);
  73. procedure pbVarIntInitUInt32(var A: TpbVarInt; const B: LongWord);
  74. procedure pbVarIntInitSInt32(var A: TpbVarInt; const B: LongInt);
  75. procedure pbVarIntInitUInt64(var A: TpbVarInt; const B: UInt64);
  76. procedure pbVarIntInitInt64(var A: TpbVarInt; const B: Int64);
  77. procedure pbVarIntInitSInt64(var A: TpbVarInt; const B: Int64);
  78. function pbVarIntToEncBuf(const A: TpbVarInt; var Buf; const BufSize: Integer): Integer;
  79. procedure pbVarIntToBinBuf(const A: TpbVarInt; var Buf; const BufSize: Integer);
  80. function pbVarIntToUInt32(const A: TpbVarInt): LongWord;
  81. function pbVarIntToSInt32(const A: TpbVarInt): LongInt;
  82. function pbVarIntToUInt64(const A: TpbVarInt): UInt64;
  83. function pbVarIntToInt64(const A: TpbVarInt): Int64;
  84. function pbVarIntToSInt64(const A: TpbVarInt): Int64;
  85. { Wire type }
  86. type
  87. TpbWireType = (
  88. pwtVarInt = 0,
  89. pwt64Bit = 1,
  90. pwtVarBytes = 2,
  91. pwtStartGroup = 3, // deprecated
  92. pwtEndGroup = 4, // deprecated
  93. pwt32Bit = 5,
  94. pwtNotUsed6 = 6,
  95. pwtNotUsed7 = 7
  96. );
  97. { Field key }
  98. function pbFieldKeyToUInt32(const FieldNumber: LongInt; const WireType: TpbWireType): LongWord;
  99. procedure pbUInt32ToFieldKey(const A: LongWord; var FieldNumber: LongInt; var WireType: TpbWireType);
  100. { Encode }
  101. type
  102. EpbEncodeError = class(Exception);
  103. function pbEncodeValueVarInt(var Buf; const BufSize: Integer; const Value: TpbVarInt): Integer;
  104. function pbEncodeValueInt32(var Buf; const BufSize: Integer; const Value: LongInt): Integer;
  105. function pbEncodeValueInt64(var Buf; const BufSize: Integer; const Value: Int64): Integer;
  106. function pbEncodeValueUInt32(var Buf; const BufSize: Integer; const Value: LongWord): Integer;
  107. function pbEncodeValueUInt64(var Buf; const BufSize: Integer; const Value: UInt64): Integer;
  108. function pbEncodeValueSInt32(var Buf; const BufSize: Integer; const Value: LongInt): Integer;
  109. function pbEncodeValueSInt64(var Buf; const BufSize: Integer; const Value: Int64): Integer;
  110. function pbEncodeValueBool(var Buf; const BufSize: Integer; const Value: Boolean): Integer;
  111. function pbEncodeValueDouble(var Buf; const BufSize: Integer; const Value: Double): Integer;
  112. function pbEncodeValueFloat(var Buf; const BufSize: Integer; const Value: Single): Integer;
  113. function pbEncodeValueFixed32(var Buf; const BufSize: Integer; const Value: LongWord): Integer;
  114. function pbEncodeValueFixed64(var Buf; const BufSize: Integer; const Value: UInt64): Integer;
  115. function pbEncodeValueSFixed32(var Buf; const BufSize: Integer; const Value: LongInt): Integer;
  116. function pbEncodeValueSFixed64(var Buf; const BufSize: Integer; const Value: Int64): Integer;
  117. function pbEncodeValueString(var Buf; const BufSize: Integer; const Value: AnsiString): Integer;
  118. function pbEncodeValueBytes(var Buf; const BufSize: Integer; const ValueBuf; const ValueBufSize: Integer): Integer;
  119. function pbEncodeFieldKey(var Buf; const BufSize: Integer; const FieldNumber: LongInt; const WireType: TpbWireType): Integer;
  120. function pbEncodeFieldVarBytesHdr(var Buf; const BufSize: Integer; const FieldNumber: LongInt; const VarBytesSize: Integer): Integer;
  121. function pbEncodeFieldVarInt(var Buf; const BufSize: Integer; const FieldNumber: LongInt; const Value: TpbVarInt): Integer;
  122. function pbEncodeFieldInt32(var Buf; const BufSize: Integer; const FieldNumber: LongInt; const Value: LongInt): Integer;
  123. function pbEncodeFieldInt64(var Buf; const BufSize: Integer; const FieldNumber: LongInt; const Value: Int64): Integer;
  124. function pbEncodeFieldUInt32(var Buf; const BufSize: Integer; const FieldNumber: LongInt; const Value: LongWord): Integer;
  125. function pbEncodeFieldUInt64(var Buf; const BufSize: Integer; const FieldNumber: LongInt; const Value: UInt64): Integer;
  126. function pbEncodeFieldSInt32(var Buf; const BufSize: Integer; const FieldNumber: LongInt; const Value: LongInt): Integer;
  127. function pbEncodeFieldSInt64(var Buf; const BufSize: Integer; const FieldNumber: LongInt; const Value: Int64): Integer;
  128. function pbEncodeFieldBool(var Buf; const BufSize: Integer; const FieldNumber: LongInt; const Value: Boolean): Integer;
  129. function pbEncodeFieldDouble(var Buf; const BufSize: Integer; const FieldNumber: LongInt; const Value: Double): Integer;
  130. function pbEncodeFieldFloat(var Buf; const BufSize: Integer; const FieldNumber: LongInt; const Value: Single): Integer;
  131. function pbEncodeFieldFixed32(var Buf; const BufSize: Integer; const FieldNumber: LongInt; const Value: LongWord): Integer;
  132. function pbEncodeFieldFixed64(var Buf; const BufSize: Integer; const FieldNumber: LongInt; const Value: UInt64): Integer;
  133. function pbEncodeFieldSFixed32(var Buf; const BufSize: Integer; const FieldNumber: LongInt; const Value: LongInt): Integer;
  134. function pbEncodeFieldSFixed64(var Buf; const BufSize: Integer; const FieldNumber: LongInt; const Value: Int64): Integer;
  135. function pbEncodeFieldString(var Buf; const BufSize: Integer; const FieldNumber: LongInt; const Value: AnsiString): Integer;
  136. function pbEncodeFieldBytes(var Buf; const BufSize: Integer; const FieldNumber: LongInt; const ValueBuf; const ValueBufSize: Integer): Integer;
  137. { Decode }
  138. type
  139. EpbDecodeError = class(Exception);
  140. function pbDecodeValueInt32(const Buf; const BufSize: Integer; var Value: LongInt): Integer;
  141. function pbDecodeValueInt64(const Buf; const BufSize: Integer; var Value: Int64): Integer;
  142. function pbDecodeValueUInt32(const Buf; const BufSize: Integer; var Value: LongWord): Integer;
  143. function pbDecodeValueUInt64(const Buf; const BufSize: Integer; var Value: UInt64): Integer;
  144. function pbDecodeValueSInt32(const Buf; const BufSize: Integer; var Value: LongInt): Integer;
  145. function pbDecodeValueSInt64(const Buf; const BufSize: Integer; var Value: Int64): Integer;
  146. function pbDecodeValueDouble(const Buf; const BufSize: Integer; var Value: Double): Integer;
  147. function pbDecodeValueFloat(const Buf; const BufSize: Integer; var Value: Single): Integer;
  148. function pbDecodeValueFixed32(const Buf; const BufSize: Integer; var Value: LongWord): Integer;
  149. function pbDecodeValueFixed64(const Buf; const BufSize: Integer; var Value: UInt64): Integer;
  150. function pbDecodeValueSFixed32(const Buf; const BufSize: Integer; var Value: LongInt): Integer;
  151. function pbDecodeValueSFixed64(const Buf; const BufSize: Integer; var Value: Int64): Integer;
  152. function pbDecodeValueBool(const Buf; const BufSize: Integer; var Value: Boolean): Integer;
  153. function pbDecodeValueString(const Buf; const BufSize: Integer; var Value: AnsiString): Integer;
  154. function pbDecodeValueBytes(const Buf; const BufSize: Integer; var ValueBuf; const ValueBufSize: Integer): Integer;
  155. type
  156. TpbProtoBufDecodeField = record
  157. FieldNum : LongInt;
  158. WireType : TpbWireType;
  159. WireDataPtr : Pointer;
  160. WireDataSize : LongInt;
  161. ValueVarInt : TpbVarInt;
  162. ValueVarBytesPtr : Pointer;
  163. ValueVarBytesLen : LongInt;
  164. end;
  165. PpbProtoBufDecodeField = ^TpbProtoBufDecodeField;
  166. TpbProtoBufDecodeFieldCallbackProc =
  167. procedure (const Field: TpbProtoBufDecodeField;
  168. const Data: Pointer);
  169. procedure pbDecodeProtoBuf(
  170. const Buf; const BufSize: Integer;
  171. const CallbackProc: TpbProtoBufDecodeFieldCallbackProc;
  172. const CallbackData: Pointer);
  173. procedure pbDecodeFieldInt32(const Field: TpbProtoBufDecodeField; var Value: LongInt);
  174. procedure pbDecodeFieldInt64(const Field: TpbProtoBufDecodeField; var Value: Int64);
  175. procedure pbDecodeFieldUInt32(const Field: TpbProtoBufDecodeField; var Value: LongWord);
  176. procedure pbDecodeFieldUInt64(const Field: TpbProtoBufDecodeField; var Value: UInt64);
  177. procedure pbDecodeFieldSInt32(const Field: TpbProtoBufDecodeField; var Value: LongInt);
  178. procedure pbDecodeFieldSInt64(const Field: TpbProtoBufDecodeField; var Value: Int64);
  179. procedure pbDecodeFieldDouble(const Field: TpbProtoBufDecodeField; var Value: Double);
  180. procedure pbDecodeFieldFloat(const Field: TpbProtoBufDecodeField; var Value: Single);
  181. procedure pbDecodeFieldFixed32(const Field: TpbProtoBufDecodeField; var Value: LongWord);
  182. procedure pbDecodeFieldFixed64(const Field: TpbProtoBufDecodeField; var Value: UInt64);
  183. procedure pbDecodeFieldSFixed32(const Field: TpbProtoBufDecodeField; var Value: LongInt);
  184. procedure pbDecodeFieldSFixed64(const Field: TpbProtoBufDecodeField; var Value: Int64);
  185. procedure pbDecodeFieldBool(const Field: TpbProtoBufDecodeField; var Value: Boolean);
  186. function pbDecodeFieldString(const Field: TpbProtoBufDecodeField; var Value: AnsiString): Integer;
  187. function pbDecodeFieldBytes(const Field: TpbProtoBufDecodeField; var ValueBuf; const ValueBufSize: Integer): Integer;
  188. { }
  189. { Test cases }
  190. { }
  191. {$IFDEF PROTOBUF_SELFTEST}
  192. procedure SelfTest;
  193. {$ENDIF}
  194. implementation
  195. { Strings }
  196. const
  197. SErr_BufferTooSmall = 'Buffer too small';
  198. SErr_Overflow = 'Overflow';
  199. SErr_InvalidVarInt = 'Invalid VarInt';
  200. SErr_InvalidBuffer = 'Invalid buffer';
  201. SErr_InvalidWireType = 'Invalid wire type';
  202. { SInt32 }
  203. // returns SInt32 encoded to LongWord using 'ZigZag' encoding
  204. function pbSInt32ToUInt32(const A: LongInt): LongWord;
  205. var I : Int64;
  206. begin
  207. if A < 0 then
  208. begin
  209. // use Int64 value to negate A without overflow
  210. I := A;
  211. I := -I;
  212. // encode ZigZag
  213. Result := (LongWord(I) - 1) * 2 + 1
  214. end
  215. else
  216. Result := LongWord(A) * 2;
  217. end;
  218. // returns SInt32 decoded from LongWord using 'ZigZag' encoding
  219. function pbUInt32ToSInt32(const A: LongWord): LongInt;
  220. begin
  221. if A and 1 <> 0 then
  222. Result := -(A div 2) - 1
  223. else
  224. Result := A div 2;
  225. end;
  226. // returns SInt64 encoded to UInt64 using 'ZigZag' encoding
  227. function pbSInt64ToUInt64(const A: Int64): UInt64;
  228. var I : UInt64;
  229. begin
  230. if A < 0 then
  231. begin
  232. // use two's complement to negate A without overflow
  233. I := not A;
  234. Inc(I);
  235. // encode ZigZag
  236. Dec(I);
  237. I := I * 2;
  238. Inc(I);
  239. Result := I;
  240. end
  241. else
  242. Result := UInt64(A) * 2;
  243. end;
  244. // returns SInt64 decoded from UInt64 using 'ZigZag' encoding
  245. function pbUInt64ToSInt64(const A: UInt64): Int64;
  246. var I : Int64;
  247. begin
  248. if A and 1 <> 0 then
  249. begin
  250. I := A shr 1;
  251. I := -I;
  252. Dec(I);
  253. Result := I;
  254. end
  255. else
  256. begin
  257. I := A shr 1;
  258. Result := I;
  259. end;
  260. end;
  261. { VarInt }
  262. // returns true if two VarInts have equal values
  263. function pbVarIntEquals(const A, B: TpbVarInt): Boolean;
  264. var I, L : Integer;
  265. begin
  266. L := A.EncSize;
  267. Result := L = B.EncSize;
  268. if not Result then
  269. exit;
  270. for I := 0 to L - 1 do
  271. if A.EncData[I] <> B.EncData[I] then
  272. begin
  273. Result := False;
  274. exit;
  275. end;
  276. end;
  277. function pbVarIntIsZero(var A: TpbVarInt): Boolean;
  278. begin
  279. Result :=
  280. (A.EncSize = 1) and
  281. (A.EncData[0] = 0);
  282. end;
  283. // initialises VarInt to zero
  284. procedure pbVarIntInitZero(var A: TpbVarInt);
  285. begin
  286. A.EncSize := 1;
  287. A.EncData[0] := 0;
  288. end;
  289. // initialises VarInt from another VarInt
  290. procedure pbVarIntInitVarInt(var A: TpbVarInt; const B: TpbVarInt);
  291. begin
  292. A.EncSize := B.EncSize;
  293. A.EncData := B.EncData;
  294. end;
  295. // initialises VarInt from a VarInt encoded buffer
  296. // encoded buffer may be larger than the VarInt encoded in it
  297. // returns the size of the VarInt in the encoded buffer
  298. function pbVarIntInitEncBuf(var A: TpbVarInt; const Buf; const BufSize: Integer): Integer;
  299. var L, I : Integer;
  300. P : PByte;
  301. C : Byte;
  302. begin
  303. L := BufSize;
  304. if L <= 0 then
  305. begin
  306. // no buffer
  307. pbVarIntInitZero(A);
  308. Result := 0;
  309. exit;
  310. end;
  311. // copy and find size
  312. I := 0;
  313. P := @Buf;
  314. while I < L do
  315. begin
  316. if I + 1 > pbMaxVarIntSizeEnc then
  317. raise EpbVarIntError.Create(SErr_Overflow);
  318. C := P^;
  319. A.EncData[I] := C;
  320. if C and $80 = 0 then
  321. break;
  322. Inc(I);
  323. Inc(P);
  324. end;
  325. if I >= L then
  326. raise EpbVarIntError.Create(SErr_InvalidBuffer);
  327. Inc(I);
  328. A.EncSize := I;
  329. Result := I;
  330. end;
  331. // initialises VarInt from integer buffer
  332. procedure pbVarIntInitBinBuf(var A: TpbVarInt; const Buf; const BufSize: Integer);
  333. var L : Integer;
  334. P : PByte;
  335. I : Integer;
  336. BinBuf : Word;
  337. BinBufBits : ShortInt;
  338. BinByte : Byte;
  339. EncSize : Byte;
  340. procedure EncodeFromBuffer;
  341. var EncByte : Byte;
  342. begin
  343. // encode 7 bits
  344. EncByte := Byte(BinBuf and $7F);
  345. if EncSize < pbMaxVarIntSizeEnc then
  346. A.EncData[EncSize] := EncByte
  347. else
  348. if EncByte <> 0 then
  349. raise EpbVarIntError.Create(SErr_Overflow);
  350. Inc(EncSize);
  351. // remove 7 bits from buffer
  352. BinBuf := BinBuf shr 7;
  353. Dec(BinBufBits, 7);
  354. end;
  355. begin
  356. L := BufSize;
  357. if L <= 0 then
  358. begin
  359. // no buffer
  360. pbVarIntInitZero(A);
  361. exit;
  362. end;
  363. // skip most significant zero bytes
  364. P := @Buf;
  365. Inc(P, L - 1);
  366. while (L > 0) and (P^ = 0) do
  367. begin
  368. Dec(P);
  369. Dec(L);
  370. end;
  371. if L <= 0 then
  372. begin
  373. // all zero values
  374. pbVarIntInitZero(A);
  375. exit;
  376. end;
  377. // encode
  378. P := @Buf;
  379. EncSize := 0;
  380. BinBuf := 0;
  381. BinBufBits := 0;
  382. for I := 0 to L - 1 do
  383. begin
  384. // buffer 8 bits
  385. BinByte := P^;
  386. BinBuf := BinBuf or (Word(BinByte) shl BinBufBits);
  387. Inc(BinBufBits, 8);
  388. Inc(P);
  389. // encode 7 bits
  390. EncodeFromBuffer;
  391. // encode further 7 bits if available
  392. if BinBufBits >= 7 then
  393. EncodeFromBuffer;
  394. end;
  395. // encode last partial byte
  396. if BinBufBits > 0 then
  397. EncodeFromBuffer;
  398. // find final encoding byte
  399. while (EncSize > 1) and (A.EncData[EncSize - 1] = 0) do
  400. Dec(EncSize);
  401. A.EncSize := EncSize;
  402. // mark non-final bytes
  403. if EncSize > 1 then
  404. begin
  405. P := @A.EncData[0];
  406. for I := 0 to EncSize - 2 do
  407. begin
  408. P^ := P^ or $80;
  409. Inc(P);
  410. end;
  411. end;
  412. end;
  413. // initialises VarInt from LongWord
  414. procedure pbVarIntInitUInt32(var A: TpbVarInt; const B: LongWord);
  415. begin
  416. if B < $80 then
  417. begin
  418. A.EncSize := 1;
  419. A.EncData[0] := Byte(B);
  420. end
  421. else
  422. if B < $4000 then
  423. begin
  424. A.EncSize := 2;
  425. A.EncData[0] := Byte(B and $7F) or $80;
  426. A.EncData[1] := Byte(B shr 7);
  427. end
  428. else
  429. if B < $200000 then
  430. begin
  431. A.EncSize := 3;
  432. A.EncData[0] := Byte(B and $7F) or $80;
  433. A.EncData[1] := Byte((B shr 7) and $7F) or $80;
  434. A.EncData[2] := Byte( B shr 14 );
  435. end
  436. else
  437. if B < $10000000 then
  438. begin
  439. A.EncSize := 4;
  440. A.EncData[0] := Byte(B and $7F) or $80;
  441. A.EncData[1] := Byte((B shr 7) and $7F) or $80;
  442. A.EncData[2] := Byte((B shr 14) and $7F) or $80;
  443. A.EncData[3] := Byte( B shr 21 );
  444. end
  445. else
  446. begin
  447. A.EncSize := 5;
  448. A.EncData[0] := Byte(B and $7F) or $80;
  449. A.EncData[1] := Byte((B shr 7) and $7F) or $80;
  450. A.EncData[2] := Byte((B shr 14) and $7F) or $80;
  451. A.EncData[3] := Byte((B shr 21) and $7F) or $80;
  452. A.EncData[4] := Byte( B shr 28 );
  453. end;
  454. end;
  455. procedure pbVarIntInitSInt32(var A: TpbVarInt; const B: LongInt);
  456. begin
  457. pbVarIntInitUInt32(A, pbSInt32ToUInt32(B));
  458. end;
  459. procedure pbVarIntInitUInt64(var A: TpbVarInt; const B: UInt64);
  460. begin
  461. pbVarIntInitBinBuf(A, B, SizeOf(B));
  462. end;
  463. procedure pbVarIntInitInt64(var A: TpbVarInt; const B: Int64);
  464. begin
  465. pbVarIntInitBinBuf(A, B, SizeOf(B));
  466. end;
  467. procedure pbVarIntInitSInt64(var A: TpbVarInt; const B: Int64);
  468. begin
  469. pbVarIntInitUInt64(A, pbSInt64ToUInt64(B));
  470. end;
  471. // converts VarInt to encoded buffer
  472. // returns size of the encoded VarInt
  473. function pbVarIntToEncBuf(const A: TpbVarInt; var Buf; const BufSize: Integer): Integer;
  474. var L : Integer;
  475. begin
  476. L := A.EncSize;
  477. if BufSize >= L then
  478. Move(A.EncData[0], Buf, L);
  479. Result := L;
  480. end;
  481. // converts VarInt to integer buffer
  482. procedure pbVarIntToBinBuf(const A: TpbVarInt; var Buf; const BufSize: Integer);
  483. var BinBuf : Word;
  484. BinBufBits : ShortInt;
  485. BinBufP : PByte;
  486. BinBufLeft : Integer;
  487. I : Integer;
  488. EncByte : Byte;
  489. EncByteFin : Boolean;
  490. EncFin : Boolean;
  491. procedure EncodeToBuffer;
  492. var BinBufByte : Byte;
  493. begin
  494. BinBufByte := Byte(BinBuf and $FF);
  495. if BinBufLeft <= 0 then
  496. if BinBufByte = 0 then
  497. exit
  498. else
  499. raise EpbVarIntError.Create(SErr_Overflow);
  500. BinBufP^ := BinBufByte;
  501. Inc(BinBufP);
  502. Dec(BinBufLeft);
  503. BinBuf := BinBuf shr 8;
  504. Dec(BinBufBits, 8);
  505. end;
  506. begin
  507. if BufSize <= 0 then
  508. raise EpbVarIntError.Create(SErr_Overflow);
  509. BinBufP := @Buf;
  510. BinBufLeft := BufSize;
  511. BinBuf := 0;
  512. BinBufBits := 0;
  513. for I := 0 to A.EncSize - 1 do
  514. begin
  515. // decode 7 bits from encoded buffer
  516. EncByte := A.EncData[I];
  517. EncFin := (I = A.EncSize - 1);
  518. EncByteFin := (EncByte and $80 = 0);
  519. if (EncFin and not EncByteFin) or
  520. (not EncFin and EncByteFin) then
  521. raise EpbVarIntError.Create(SErr_InvalidVarInt);
  522. BinBuf := BinBuf or (Word(EncByte and $7F) shl BinBufBits);
  523. Inc(BinBufBits, 7);
  524. // encode 8 bits to binary buffer if available
  525. if BinBufBits >= 8 then
  526. EncodeToBuffer;
  527. end;
  528. // encode final partial byte
  529. if BinBufBits > 0 then
  530. EncodeToBuffer;
  531. // fill rest of binary buffer with zero
  532. while BinBufLeft > 0 do
  533. begin
  534. BinBufP^ := 0;
  535. Inc(BinBufP);
  536. Dec(BinBufLeft);
  537. end;
  538. end;
  539. // returns VarInt value as LongWord
  540. function pbVarIntToUInt32(const A: TpbVarInt): LongWord;
  541. var B : LongWord;
  542. I : Byte;
  543. EncByte : Byte;
  544. begin
  545. Assert(A.EncSize > 0);
  546. Assert(A.EncSize <= pbMaxVarIntSizeEnc);
  547. // decode
  548. B := 0;
  549. I := 0;
  550. while I < A.EncSize do
  551. begin
  552. EncByte := A.EncData[I];
  553. if I = 4 then
  554. if EncByte and $F0 <> 0 then
  555. raise EpbVarIntError.Create(SErr_Overflow);
  556. B := B or (LongWord(EncByte and $7F) shl (I * 7));
  557. Inc(I);
  558. if EncByte and $80 = 0 then // final byte marker
  559. begin
  560. if I < A.EncSize then // final byte marker before final byte reached
  561. raise EpbVarIntError.Create(SErr_InvalidVarInt);
  562. // finished
  563. Result := B;
  564. exit;
  565. end;
  566. end;
  567. // final byte reached without final byte marker
  568. raise EpbVarIntError.Create(SErr_InvalidVarInt);
  569. end;
  570. function pbVarIntToSInt32(const A: TpbVarInt): LongInt;
  571. begin
  572. Result := pbUInt32ToSInt32(pbVarIntToUInt32(A));
  573. end;
  574. function pbVarIntToUInt64(const A: TpbVarInt): UInt64;
  575. begin
  576. pbVarIntToBinBuf(A, Result, SizeOf(Result));
  577. end;
  578. function pbVarIntToInt64(const A: TpbVarInt): Int64;
  579. begin
  580. pbVarIntToBinBuf(A, Result, SizeOf(Result));
  581. end;
  582. function pbVarIntToSInt64(const A: TpbVarInt): Int64;
  583. begin
  584. Result := pbUInt64ToSInt64(pbVarIntToUInt64(A));
  585. end;
  586. { Field key }
  587. function pbFieldKeyToUInt32(const FieldNumber: LongInt; const WireType: TpbWireType): LongWord;
  588. begin
  589. Result := Ord(WireType) or (FieldNumber shl 3);
  590. end;
  591. procedure pbUInt32ToFieldKey(const A: LongWord; var FieldNumber: LongInt; var WireType: TpbWireType);
  592. begin
  593. WireType := TpbWireType(A and 7);
  594. FieldNumber := A shr 3;
  595. end;
  596. { Encode }
  597. function pbEncodeValueVarInt(var Buf; const BufSize: Integer; const Value: TpbVarInt): Integer;
  598. begin
  599. Result := pbVarIntToEncBuf(Value, Buf, BufSize);
  600. end;
  601. function pbEncodeValueInt32(var Buf; const BufSize: Integer; const Value: LongInt): Integer;
  602. var
  603. A : TpbVarInt;
  604. begin
  605. pbVarIntInitUInt32(A, LongWord(Value));
  606. Result := pbVarIntToEncBuf(A, Buf, BufSize);
  607. end;
  608. function pbEncodeValueInt64(var Buf; const BufSize: Integer; const Value: Int64): Integer;
  609. var
  610. A : TpbVarInt;
  611. begin
  612. pbVarIntInitBinBuf(A, Value, SizeOf(Value));
  613. Result := pbVarIntToEncBuf(A, Buf, BufSize);
  614. end;
  615. function pbEncodeValueUInt32(var Buf; const BufSize: Integer; const Value: LongWord): Integer;
  616. var
  617. A : TpbVarInt;
  618. begin
  619. pbVarIntInitUInt32(A, Value);
  620. Result := pbVarIntToEncBuf(A, Buf, BufSize);
  621. end;
  622. function pbEncodeValueUInt64(var Buf; const BufSize: Integer; const Value: UInt64): Integer;
  623. var
  624. A : TpbVarInt;
  625. begin
  626. pbVarIntInitBinBuf(A, Value, SizeOf(Value));
  627. Result := pbVarIntToEncBuf(A, Buf, BufSize);
  628. end;
  629. function pbEncodeValueSInt32(var Buf; const BufSize: Integer; const Value: LongInt): Integer;
  630. var
  631. A : TpbVarInt;
  632. begin
  633. pbVarIntInitSInt32(A, Value);
  634. Result := pbVarIntToEncBuf(A, Buf, BufSize);
  635. end;
  636. function pbEncodeValueSInt64(var Buf; const BufSize: Integer; const Value: Int64): Integer;
  637. var
  638. A : TpbVarInt;
  639. begin
  640. pbVarIntInitSInt64(A, Value);
  641. Result := pbVarIntToEncBuf(A, Buf, BufSize);
  642. end;
  643. function pbEncodeValueBool(var Buf; const BufSize: Integer; const Value: Boolean): Integer;
  644. var
  645. A : TpbVarInt;
  646. begin
  647. pbVarIntInitUInt32(A, Ord(Value));
  648. Result := pbVarIntToEncBuf(A, Buf, BufSize);
  649. end;
  650. function pbEncodeValueDouble(var Buf; const BufSize: Integer; const Value: Double): Integer;
  651. begin
  652. if BufSize >= SizeOf(Value) then
  653. PDouble(@Buf)^ := Value;
  654. Result := SizeOf(Value);
  655. end;
  656. function pbEncodeValueFloat(var Buf; const BufSize: Integer; const Value: Single): Integer;
  657. begin
  658. if BufSize >= SizeOf(Value) then
  659. PSingle(@Buf)^ := Value;
  660. Result := SizeOf(Value);
  661. end;
  662. function pbEncodeValueFixed32(var Buf; const BufSize: Integer; const Value: LongWord): Integer;
  663. begin
  664. if BufSize >= SizeOf(Value) then
  665. PLongWord(@Buf)^ := Value;
  666. Result := SizeOf(Value);
  667. end;
  668. function pbEncodeValueFixed64(var Buf; const BufSize: Integer; const Value: UInt64): Integer;
  669. begin
  670. if BufSize >= SizeOf(Value) then
  671. PUInt64(@Buf)^ := Value;
  672. Result := SizeOf(Value);
  673. end;
  674. function pbEncodeValueSFixed32(var Buf; const BufSize: Integer; const Value: LongInt): Integer;
  675. begin
  676. if BufSize >= SizeOf(Value) then
  677. PLongInt(@Buf)^ := Value;
  678. Result := SizeOf(Value);
  679. end;
  680. function pbEncodeValueSFixed64(var Buf; const BufSize: Integer; const Value: Int64): Integer;
  681. begin
  682. if BufSize >= SizeOf(Value) then
  683. PInt64(@Buf)^ := Value;
  684. Result := SizeOf(Value);
  685. end;
  686. function pbEncodeValueString(var Buf; const BufSize: Integer; const Value: AnsiString): Integer;
  687. var
  688. P : PByte;
  689. L, N, J : Integer;
  690. A : TpbVarInt;
  691. begin
  692. P := @Buf;
  693. L := BufSize;
  694. // string length as VarInt
  695. N := Length(Value);
  696. pbVarIntInitUInt32(A, LongWord(N));
  697. J := pbVarIntToEncBuf(A, P^, L);
  698. Inc(P, J);
  699. Dec(L, J);
  700. // string content
  701. if N > 0 then
  702. begin
  703. if L >= N then
  704. Move(PAnsiChar(Value)^, P^, N);
  705. Dec(L, N);
  706. end;
  707. Result := BufSize - L;
  708. end;
  709. function pbEncodeValueBytes(var Buf; const BufSize: Integer; const ValueBuf; const ValueBufSize: Integer): Integer;
  710. var
  711. P : PByte;
  712. L, N, J : Integer;
  713. A : TpbVarInt;
  714. begin
  715. P := @Buf;
  716. L := BufSize;
  717. // buffer size as VarInt
  718. N := ValueBufSize;
  719. pbVarIntInitUInt32(A, LongWord(N));
  720. J := pbVarIntToEncBuf(A, P^, L);
  721. Inc(P, J);
  722. Dec(L, J);
  723. // buffer content
  724. if N > 0 then
  725. begin
  726. if L >= N then
  727. Move(ValueBuf, P^, N);
  728. Dec(L, N);
  729. end;
  730. Result := BufSize - L;
  731. end;
  732. function pbEncodeFieldKey(var Buf; const BufSize: Integer;
  733. const FieldNumber: LongInt; const WireType: TpbWireType): Integer;
  734. var
  735. FieldKey : LongWord;
  736. A : TpbVarInt;
  737. begin
  738. FieldKey := pbFieldKeyToUInt32(FieldNumber, WireType);
  739. pbVarIntInitUInt32(A, FieldKey);
  740. Result := pbVarIntToEncBuf(A, Buf, BufSize);
  741. end;
  742. function pbEncodeFieldVarBytesHdr(var Buf; const BufSize: Integer;
  743. const FieldNumber: LongInt; const VarBytesSize: Integer): Integer;
  744. var
  745. P : PByte;
  746. L : Integer;
  747. I : Integer;
  748. A : TpbVarInt;
  749. begin
  750. if VarBytesSize < 0 then
  751. raise EpbEncodeError.Create(SErr_InvalidBuffer);
  752. P := @Buf;
  753. L := BufSize;
  754. I := pbEncodeFieldKey(P^, L, FieldNumber, pwtVarBytes);
  755. Dec(L, I);
  756. Inc(P, I);
  757. pbVarIntInitUInt32(A, LongWord(VarBytesSize));
  758. I := pbVarIntToEncBuf(A, P^, L);
  759. Dec(L, I);
  760. Result := BufSize - L;
  761. end;
  762. function pbEncodeFieldVarInt(var Buf; const BufSize: Integer;
  763. const FieldNumber: LongInt; const Value: TpbVarInt): Integer;
  764. var
  765. P : PByte;
  766. L : Integer;
  767. I : Integer;
  768. begin
  769. P := @Buf;
  770. L := BufSize;
  771. I := pbEncodeFieldKey(P^, L, FieldNumber, pwtVarInt);
  772. Inc(P, I);
  773. Dec(L, I);
  774. I := pbVarIntToEncBuf(Value, P^, L);
  775. Dec(L, I);
  776. Result := BufSize - L;
  777. end;
  778. function pbEncodeFieldInt32(var Buf; const BufSize: Integer;
  779. const FieldNumber: LongInt; const Value: LongInt): Integer;
  780. var
  781. A : TpbVarInt;
  782. begin
  783. pbVarIntInitUInt32(A, LongWord(Value));
  784. Result := pbEncodeFieldVarInt(Buf, BufSize, FieldNumber, A);
  785. end;
  786. function pbEncodeFieldInt64(var Buf; const BufSize: Integer;
  787. const FieldNumber: LongInt; const Value: Int64): Integer;
  788. var
  789. A : TpbVarInt;
  790. begin
  791. pbVarIntInitBinBuf(A, Value, SizeOf(Value));
  792. Result := pbEncodeFieldVarInt(Buf, BufSize, FieldNumber, A);
  793. end;
  794. function pbEncodeFieldUInt32(var Buf; const BufSize: Integer;
  795. const FieldNumber: LongInt; const Value: LongWord): Integer;
  796. var
  797. A : TpbVarInt;
  798. begin
  799. pbVarIntInitUInt32(A, Value);
  800. Result := pbEncodeFieldVarInt(Buf, BufSize, FieldNumber, A);
  801. end;
  802. function pbEncodeFieldUInt64(var Buf; const BufSize: Integer;
  803. const FieldNumber: LongInt; const Value: UInt64): Integer;
  804. var
  805. A : TpbVarInt;
  806. begin
  807. pbVarIntInitBinBuf(A, Value, SizeOf(Value));
  808. Result := pbEncodeFieldVarInt(Buf, BufSize, FieldNumber, A);
  809. end;
  810. function pbEncodeFieldSInt32(var Buf; const BufSize: Integer;
  811. const FieldNumber: LongInt; const Value: LongInt): Integer;
  812. var
  813. A : TpbVarInt;
  814. begin
  815. pbVarIntInitSInt32(A, Value);
  816. Result := pbEncodeFieldVarInt(Buf, BufSize, FieldNumber, A);
  817. end;
  818. function pbEncodeFieldSInt64(var Buf; const BufSize: Integer;
  819. const FieldNumber: LongInt; const Value: Int64): Integer;
  820. var
  821. A : TpbVarInt;
  822. begin
  823. pbVarIntInitSInt64(A, Value);
  824. Result := pbEncodeFieldVarInt(Buf, BufSize, FieldNumber, A);
  825. end;
  826. function pbEncodeFieldBool(var Buf; const BufSize: Integer;
  827. const FieldNumber: LongInt; const Value: Boolean): Integer;
  828. var
  829. A : TpbVarInt;
  830. begin
  831. pbVarIntInitUInt32(A, Ord(Value));
  832. Result := pbEncodeFieldVarInt(Buf, BufSize, FieldNumber, A);
  833. end;
  834. function pbEncodeFieldDouble(var Buf; const BufSize: Integer;
  835. const FieldNumber: LongInt; const Value: Double): Integer;
  836. var
  837. P : PByte;
  838. L : Integer;
  839. I : Integer;
  840. begin
  841. P := @Buf;
  842. L := BufSize;
  843. I := pbEncodeFieldKey(P^, L, FieldNumber, pwt64Bit);
  844. Inc(P, I);
  845. Dec(L, I);
  846. I := pbEncodeValueDouble(P^, L, Value);
  847. Dec(L, I);
  848. Result := BufSize - L;
  849. end;
  850. function pbEncodeFieldFloat(var Buf; const BufSize: Integer;
  851. const FieldNumber: LongInt; const Value: Single): Integer;
  852. var
  853. P : PByte;
  854. L : Integer;
  855. I : Integer;
  856. begin
  857. P := @Buf;
  858. L := BufSize;
  859. I := pbEncodeFieldKey(P^, L, FieldNumber, pwt32Bit);
  860. Inc(P, I);
  861. Dec(L, I);
  862. I := pbEncodeValueFloat(P^, L, Value);
  863. Dec(L, I);
  864. Result := BufSize - L;
  865. end;
  866. function pbEncodeFieldFixed32(var Buf; const BufSize: Integer;
  867. const FieldNumber: LongInt; const Value: LongWord): Integer;
  868. var
  869. P : PByte;
  870. L : Integer;
  871. I : Integer;
  872. begin
  873. P := @Buf;
  874. L := BufSize;
  875. I := pbEncodeFieldKey(P^, L, FieldNumber, pwt32Bit);
  876. Inc(P, I);
  877. Dec(L, I);
  878. I := pbEncodeValueFixed32(P^, L, Value);
  879. Dec(L, I);
  880. Result := BufSize - L;
  881. end;
  882. function pbEncodeFieldFixed64(var Buf; const BufSize: Integer;
  883. const FieldNumber: LongInt; const Value: UInt64): Integer;
  884. var
  885. P : PByte;
  886. L : Integer;
  887. I : Integer;
  888. begin
  889. P := @Buf;
  890. L := BufSize;
  891. I := pbEncodeFieldKey(P^, L, FieldNumber, pwt64Bit);
  892. Inc(P, I);
  893. Dec(L, I);
  894. I := pbEncodeValueFixed64(P^, L, Value);
  895. Dec(L, I);
  896. Result := BufSize - L;
  897. end;
  898. function pbEncodeFieldSFixed32(var Buf; const BufSize: Integer;
  899. const FieldNumber: LongInt; const Value: LongInt): Integer;
  900. var
  901. P : PByte;
  902. L : Integer;
  903. I : Integer;
  904. begin
  905. P := @Buf;
  906. L := BufSize;
  907. I := pbEncodeFieldKey(P^, L, FieldNumber, pwt32Bit);
  908. Inc(P, I);
  909. Dec(L, I);
  910. I := pbEncodeValueSFixed32(P^, L, Value);
  911. Dec(L, I);
  912. Result := BufSize - L;
  913. end;
  914. function pbEncodeFieldSFixed64(var Buf; const BufSize: Integer;
  915. const FieldNumber: LongInt; const Value: Int64): Integer;
  916. var
  917. P : PByte;
  918. L : Integer;
  919. I : Integer;
  920. begin
  921. P := @Buf;
  922. L := BufSize;
  923. I := pbEncodeFieldKey(P^, L, FieldNumber, pwt64Bit);
  924. Inc(P, I);
  925. Dec(L, I);
  926. I := pbEncodeValueSFixed64(P^, L, Value);
  927. Dec(L, I);
  928. Result := BufSize - L;
  929. end;
  930. function pbEncodeFieldString(var Buf; const BufSize: Integer;
  931. const FieldNumber: LongInt; const Value: AnsiString): Integer;
  932. var
  933. P : PByte;
  934. L : Integer;
  935. I : Integer;
  936. begin
  937. P := @Buf;
  938. L := BufSize;
  939. I := pbEncodeFieldKey(P^, L, FieldNumber, pwtVarBytes);
  940. Inc(P, I);
  941. Dec(L, I);
  942. I := pbEncodeValueString(P^, L, Value);
  943. Dec(L, I);
  944. Result := BufSize - L;
  945. end;
  946. function pbEncodeFieldBytes(var Buf; const BufSize: Integer;
  947. const FieldNumber: LongInt; const ValueBuf; const ValueBufSize: Integer): Integer;
  948. var
  949. P : PByte;
  950. L : Integer;
  951. I : Integer;
  952. begin
  953. if ValueBufSize < 0 then
  954. raise EpbEncodeError.Create(SErr_InvalidBuffer);
  955. P := @Buf;
  956. L := BufSize;
  957. I := pbEncodeFieldKey(P^, L, FieldNumber, pwtVarBytes);
  958. Inc(P, I);
  959. Dec(L, I);
  960. I := pbEncodeValueBytes(P^, L, ValueBuf, ValueBufSize);
  961. Dec(L, I);
  962. Result := BufSize - L;
  963. end;
  964. { Decode }
  965. function pbDecodeValueInt32(const Buf; const BufSize: Integer; var Value: LongInt): Integer;
  966. var
  967. A : TpbVarInt;
  968. begin
  969. Result := pbVarIntInitEncBuf(A, Buf, BufSize);
  970. pbVarIntToBinBuf(A, Value, SizeOf(Value));
  971. end;
  972. function pbDecodeValueInt64(const Buf; const BufSize: Integer; var Value: Int64): Integer;
  973. var
  974. A : TpbVarInt;
  975. begin
  976. Result := pbVarIntInitEncBuf(A, Buf, BufSize);
  977. pbVarIntToBinBuf(A, Value, SizeOf(Value));
  978. end;
  979. function pbDecodeValueUInt32(const Buf; const BufSize: Integer; var Value: LongWord): Integer;
  980. var
  981. A : TpbVarInt;
  982. begin
  983. Result := pbVarIntInitEncBuf(A, Buf, BufSize);
  984. pbVarIntToBinBuf(A, Value, SizeOf(Value));
  985. end;
  986. function pbDecodeValueUInt64(const Buf; const BufSize: Integer; var Value: UInt64): Integer;
  987. var
  988. A : TpbVarInt;
  989. begin
  990. Result := pbVarIntInitEncBuf(A, Buf, BufSize);
  991. pbVarIntToBinBuf(A, Value, SizeOf(Value));
  992. end;
  993. function pbDecodeValueSInt32(const Buf; const BufSize: Integer; var Value: LongInt): Integer;
  994. var
  995. A : TpbVarInt;
  996. begin
  997. Result := pbVarIntInitEncBuf(A, Buf, BufSize);
  998. Value := pbVarIntToSInt32(A);
  999. end;
  1000. function pbDecodeValueSInt64(const Buf; const BufSize: Integer; var Value: Int64): Integer;
  1001. var
  1002. A : TpbVarInt;
  1003. begin
  1004. Result := pbVarIntInitEncBuf(A, Buf, BufSize);
  1005. Value := pbVarIntToSInt64(A);
  1006. end;
  1007. function pbDecodeValueDouble(const Buf; const BufSize: Integer; var Value: Double): Integer;
  1008. begin
  1009. if BufSize < SizeOf(Value) then
  1010. raise EpbDecodeError.Create(SErr_InvalidBuffer);
  1011. Value := PDouble(@Buf)^;
  1012. Result := SizeOf(Value);
  1013. end;
  1014. function pbDecodeValueFloat(const Buf; const BufSize: Integer; var Value: Single): Integer;
  1015. begin
  1016. if BufSize < SizeOf(Value) then
  1017. raise EpbDecodeError.Create(SErr_InvalidBuffer);
  1018. Value := PSingle(@Buf)^;
  1019. Result := SizeOf(Value);
  1020. end;
  1021. function pbDecodeValueFixed32(const Buf; const BufSize: Integer; var Value: LongWord): Integer;
  1022. begin
  1023. if BufSize < SizeOf(Value) then
  1024. raise EpbDecodeError.Create(SErr_InvalidBuffer);
  1025. Value := PLongWord(@Buf)^;
  1026. Result := SizeOf(Value);
  1027. end;
  1028. function pbDecodeValueFixed64(const Buf; const BufSize: Integer; var Value: UInt64): Integer;
  1029. begin
  1030. if BufSize < SizeOf(Value) then
  1031. raise EpbDecodeError.Create(SErr_InvalidBuffer);
  1032. Value := PUInt64(@Buf)^;
  1033. Result := SizeOf(Value);
  1034. end;
  1035. function pbDecodeValueSFixed32(const Buf; const BufSize: Integer; var Value: LongInt): Integer;
  1036. begin
  1037. if BufSize < SizeOf(Value) then
  1038. raise EpbDecodeError.Create(SErr_InvalidBuffer);
  1039. Value := PLongInt(@Buf)^;
  1040. Result := SizeOf(Value);
  1041. end;
  1042. function pbDecodeValueSFixed64(const Buf; const BufSize: Integer; var Value: Int64): Integer;
  1043. begin
  1044. if BufSize < SizeOf(Value) then
  1045. raise EpbDecodeError.Create(SErr_InvalidBuffer);
  1046. Value := PInt64(@Buf)^;
  1047. Result := SizeOf(Value);
  1048. end;
  1049. function pbDecodeValueBool(const Buf; const BufSize: Integer; var Value: Boolean): Integer;
  1050. var
  1051. A : TpbVarInt;
  1052. begin
  1053. Result := pbVarIntInitEncBuf(A, Buf, BufSize);
  1054. Value := not pbVarIntIsZero(A);
  1055. end;
  1056. function pbDecodeValueString(const Buf; const BufSize: Integer; var Value: AnsiString): Integer;
  1057. var
  1058. P : PByte;
  1059. L, I, N : Integer;
  1060. S : AnsiString;
  1061. begin
  1062. P := @Buf;
  1063. L := BufSize;
  1064. I := pbDecodeValueInt32(P^, L, N);
  1065. Dec(L, I);
  1066. Inc(P, I);
  1067. if L < N then
  1068. raise EpbDecodeError.Create(SErr_InvalidBuffer);
  1069. SetLength(S, N);
  1070. if N > 0 then
  1071. begin
  1072. Move(P^, PAnsiChar(S)^, N);
  1073. Dec(L, N);
  1074. end;
  1075. Value := S;
  1076. Result:= BufSize - L;
  1077. end;
  1078. function pbDecodeValueBytes(const Buf; const BufSize: Integer; var ValueBuf; const ValueBufSize: Integer): Integer;
  1079. var
  1080. P : PByte;
  1081. L, I, N : Integer;
  1082. begin
  1083. P := @Buf;
  1084. L := BufSize;
  1085. I := pbDecodeValueInt32(P^, L, N);
  1086. Dec(L, I);
  1087. Inc(P, I);
  1088. if L < N then
  1089. raise EpbDecodeError.Create(SErr_InvalidBuffer);
  1090. if N > 0 then
  1091. begin
  1092. if ValueBufSize < N then
  1093. raise EpbDecodeError.Create(SErr_InvalidBuffer);
  1094. Move(P^, ValueBuf, N);
  1095. Dec(L, N);
  1096. end;
  1097. Result:= BufSize - L;
  1098. end;
  1099. procedure pbDecodeProtoBuf(
  1100. const Buf; const BufSize: Integer;
  1101. const CallbackProc: TpbProtoBufDecodeFieldCallbackProc;
  1102. const CallbackData: Pointer);
  1103. var
  1104. P : PByte;
  1105. L : Integer;
  1106. I : Integer;
  1107. A : TpbVarInt;
  1108. Q : PByte;
  1109. WireSize : Integer;
  1110. Key32 : LongWord;
  1111. Field : TpbProtoBufDecodeField;
  1112. begin
  1113. P := @Buf;
  1114. L := BufSize;
  1115. while L > 0 do
  1116. begin
  1117. // decode field key
  1118. I := pbVarIntInitEncBuf(A, P^, L);
  1119. Assert(I > 0);
  1120. Inc(P, I);
  1121. Dec(L, I);
  1122. Key32 := pbVarIntToUInt32(A);
  1123. pbUInt32ToFieldKey(Key32, Field.FieldNum, Field.WireType);
  1124. // decode wire data
  1125. Field.WireDataPtr := P;
  1126. case Field.WireType of
  1127. pwt32Bit : WireSize := 4;
  1128. pwt64Bit : WireSize := 8;
  1129. pwtVarInt : WireSize := pbVarIntInitEncBuf(Field.ValueVarInt, P^, L);
  1130. pwtVarBytes :
  1131. begin
  1132. // VarBytes size
  1133. I := pbVarIntInitEncBuf(A, P^, L);
  1134. Field.ValueVarBytesLen := pbVarIntToUInt32(A);
  1135. // VarBytes data
  1136. Q := P;
  1137. Inc(Q, I);
  1138. Field.ValueVarBytesPtr := Q;
  1139. // wire size
  1140. WireSize := I + Field.ValueVarBytesLen;
  1141. end;
  1142. else
  1143. raise EpbDecodeError.Create(SErr_InvalidBuffer); // unrecognised wire type
  1144. end;
  1145. Field.WireDataSize := WireSize;
  1146. if WireSize > L then
  1147. raise EpbDecodeError.Create(SErr_InvalidBuffer); // incomplete/bad buffer
  1148. Inc(P, WireSize);
  1149. Dec(L, WireSize);
  1150. // field callback
  1151. if Assigned(CallbackProc) then
  1152. CallbackProc(Field, CallbackData);
  1153. end;
  1154. end;
  1155. procedure pbDecodeFieldInt32(const Field: TpbProtoBufDecodeField; var Value: LongInt);
  1156. begin
  1157. case Field.WireType of
  1158. pwt32Bit : Value := PLongInt(Field.WireDataPtr)^;
  1159. pwtVarInt : pbVarIntToBinBuf(Field.ValueVarInt, Value, SizeOf(Value));
  1160. else
  1161. raise EpbDecodeError.Create(SErr_InvalidWireType);
  1162. end;
  1163. end;
  1164. procedure pbDecodeFieldInt64(const Field: TpbProtoBufDecodeField; var Value: Int64);
  1165. begin
  1166. case Field.WireType of
  1167. pwt32Bit : Value := PLongInt(Field.WireDataPtr)^;
  1168. pwt64Bit : Value := PInt64(Field.WireDataPtr)^;
  1169. pwtVarInt : pbVarIntToBinBuf(Field.ValueVarInt, Value, SizeOf(Value));
  1170. else
  1171. raise EpbDecodeError.Create(SErr_InvalidWireType);
  1172. end;
  1173. end;
  1174. procedure pbDecodeFieldUInt32(const Field: TpbProtoBufDecodeField; var Value: LongWord);
  1175. begin
  1176. case Field.WireType of
  1177. pwt32Bit : Value := PLongWord(Field.WireDataPtr)^;
  1178. pwtVarInt : Value := pbVarIntToUInt32(Field.ValueVarInt);
  1179. else
  1180. raise EpbDecodeError.Create(SErr_InvalidWireType);
  1181. end;
  1182. end;
  1183. procedure pbDecodeFieldUInt64(const Field: TpbProtoBufDecodeField; var Value: UInt64);
  1184. begin
  1185. case Field.WireType of
  1186. pwt32Bit : Value := PLongWord(Field.WireDataPtr)^;
  1187. pwt64Bit : Value := PUInt64(Field.WireDataPtr)^;
  1188. pwtVarInt : pbVarIntToBinBuf(Field.ValueVarInt, Value, SizeOf(Value));
  1189. else
  1190. raise EpbDecodeError.Create(SErr_InvalidWireType);
  1191. end;
  1192. end;
  1193. procedure pbDecodeFieldSInt32(const Field: TpbProtoBufDecodeField; var Value: LongInt);
  1194. begin
  1195. case Field.WireType of
  1196. pwt32Bit : Value := PLongInt(Field.WireDataPtr)^;
  1197. pwtVarInt : Value := pbVarIntToSInt32(Field.ValueVarInt);
  1198. else
  1199. raise EpbDecodeError.Create(SErr_InvalidWireType);
  1200. end;
  1201. end;
  1202. procedure pbDecodeFieldSInt64(const Field: TpbProtoBufDecodeField; var Value: Int64);
  1203. begin
  1204. case Field.WireType of
  1205. pwt32Bit : Value := PLongInt(Field.WireDataPtr)^;
  1206. pwt64Bit : Value := PInt64(Field.WireDataPtr)^;
  1207. pwtVarInt : Value := pbVarIntToSInt64(Field.ValueVarInt);
  1208. else
  1209. raise EpbDecodeError.Create(SErr_InvalidWireType);
  1210. end;
  1211. end;
  1212. procedure pbDecodeFieldDouble(const Field: TpbProtoBufDecodeField; var Value: Double);
  1213. begin
  1214. case Field.WireType of
  1215. pwt32Bit : Value := PSingle(Field.WireDataPtr)^;
  1216. pwt64Bit : Value := PDouble(Field.WireDataPtr)^;
  1217. else
  1218. raise EpbDecodeError.Create(SErr_InvalidWireType);
  1219. end;
  1220. end;
  1221. procedure pbDecodeFieldFloat(const Field: TpbProtoBufDecodeField; var Value: Single);
  1222. begin
  1223. case Field.WireType of
  1224. pwt32Bit : Value := PSingle(Field.WireDataPtr)^;
  1225. else
  1226. raise EpbDecodeError.Create(SErr_InvalidWireType);
  1227. end;
  1228. end;
  1229. procedure pbDecodeFieldFixed32(const Field: TpbProtoBufDecodeField; var Value: LongWord);
  1230. begin
  1231. case Field.WireType of
  1232. pwt32Bit : Value := PLongWord(Field.WireDataPtr)^;
  1233. pwtVarInt : Value := pbVarIntToUInt32(Field.ValueVarInt);
  1234. else
  1235. raise EpbDecodeError.Create(SErr_InvalidWireType);
  1236. end;
  1237. end;
  1238. procedure pbDecodeFieldFixed64(const Field: TpbProtoBufDecodeField; var Value: UInt64);
  1239. begin
  1240. case Field.WireType of
  1241. pwt32Bit : Value := PLongWord(Field.WireDataPtr)^;
  1242. pwt64Bit : Value := PUInt64(Field.WireDataPtr)^;
  1243. else
  1244. raise EpbDecodeError.Create(SErr_InvalidWireType);
  1245. end;
  1246. end;
  1247. procedure pbDecodeFieldSFixed32(const Field: TpbProtoBufDecodeField; var Value: LongInt);
  1248. begin
  1249. case Field.WireType of
  1250. pwt32Bit : Value := PLongInt(Field.WireDataPtr)^;
  1251. else
  1252. raise EpbDecodeError.Create(SErr_InvalidWireType);
  1253. end;
  1254. end;
  1255. procedure pbDecodeFieldSFixed64(const Field: TpbProtoBufDecodeField; var Value: Int64);
  1256. begin
  1257. case Field.WireType of
  1258. pwt32Bit : Value := PLongInt(Field.WireDataPtr)^;
  1259. pwt64Bit : Value := PInt64(Field.WireDataPtr)^;
  1260. else
  1261. raise EpbDecodeError.Create(SErr_InvalidWireType);
  1262. end;
  1263. end;
  1264. procedure pbDecodeFieldBool(const Field: TpbProtoBufDecodeField; var Value: Boolean);
  1265. begin
  1266. case Field.WireType of
  1267. pwt32Bit : Value := PLongInt(Field.WireDataPtr)^ <> 0;
  1268. pwt64Bit : Value := PInt64(Field.WireDataPtr)^ <> 0;
  1269. pwtVarInt : Value := pbVarIntToUInt32(Field.ValueVarInt) <> 0;
  1270. else
  1271. raise EpbDecodeError.Create(SErr_InvalidWireType);
  1272. end;
  1273. end;
  1274. function pbDecodeFieldString(const Field: TpbProtoBufDecodeField; var Value: AnsiString): Integer;
  1275. var
  1276. S : AnsiString;
  1277. L : Integer;
  1278. begin
  1279. case Field.WireType of
  1280. pwtVarBytes :
  1281. begin
  1282. L := Field.ValueVarBytesLen;
  1283. SetLength(S, L);
  1284. if L > 0 then
  1285. Move(Field.ValueVarBytesPtr^, PAnsiChar(S)^, L);
  1286. Value := S;
  1287. Result := L;
  1288. end;
  1289. else
  1290. raise EpbDecodeError.Create(SErr_InvalidWireType);
  1291. end;
  1292. end;
  1293. function pbDecodeFieldBytes(const Field: TpbProtoBufDecodeField; var ValueBuf; const ValueBufSize: Integer): Integer;
  1294. var
  1295. L : Integer;
  1296. begin
  1297. case Field.WireType of
  1298. pwtVarBytes :
  1299. begin
  1300. L := Field.ValueVarBytesLen;
  1301. if ValueBufSize < L then
  1302. raise EpbDecodeError.Create(SErr_BufferTooSmall);
  1303. if L > 0 then
  1304. Move(Field.ValueVarBytesPtr^, ValueBuf, L);
  1305. Result := L;
  1306. end;
  1307. else
  1308. raise EpbDecodeError.Create(SErr_InvalidWireType);
  1309. end;
  1310. end;
  1311. { }
  1312. { Test cases }
  1313. { }
  1314. {$IFDEF PROTOBUF_SELFTEST}
  1315. {$ASSERTIONS ON}
  1316. {$IFNDEF SupportsUInt64}{$WARNINGS OFF}{$ENDIF}
  1317. procedure SelfTest_VarInt;
  1318. var I, J : TpbVarInt;
  1319. A : LongWord;
  1320. begin
  1321. // InitZero
  1322. pbVarIntInitZero(I);
  1323. Assert(I.EncSize = 1);
  1324. Assert(I.EncData[0] = 0);
  1325. Assert(pbVarIntToUInt32(I) = 0);
  1326. // pbVarIntEquals
  1327. pbVarIntInitUInt32(I, 0);
  1328. pbVarIntInitZero(J);
  1329. Assert(pbVarIntEquals(I, J));
  1330. pbVarIntInitUInt32(I, 0);
  1331. pbVarIntInitUInt32(J, 1);
  1332. Assert(not pbVarIntEquals(I, J));
  1333. // pbVarIntInitLongWord
  1334. pbVarIntInitUInt32(I, 0);
  1335. Assert(I.EncSize = 1);
  1336. Assert(I.EncData[0] = 0);
  1337. Assert(pbVarIntToUInt32(I) = 0);
  1338. pbVarIntInitUInt32(I, 1);
  1339. Assert(I.EncSize = 1);
  1340. Assert(I.EncData[0] = 1);
  1341. Assert(pbVarIntToUInt32(I) = 1);
  1342. pbVarIntInitUInt32(I, $7F);
  1343. Assert(I.EncSize = 1);
  1344. Assert(I.EncData[0] = $7F);
  1345. Assert(pbVarIntToUInt32(I) = $7F);
  1346. pbVarIntInitUInt32(I, $80);
  1347. Assert(I.EncSize = 2);
  1348. Assert(I.EncData[0] = $80);
  1349. Assert(I.EncData[1] = $01);
  1350. Assert(pbVarIntToUInt32(I) = $80);
  1351. pbVarIntInitUInt32(I, $81);
  1352. Assert(I.EncSize = 2);
  1353. Assert(I.EncData[0] = $81);
  1354. Assert(I.EncData[1] = $01);
  1355. Assert(pbVarIntToUInt32(I) = $81);
  1356. pbVarIntInitUInt32(I, $100);
  1357. Assert(I.EncSize = 2);
  1358. Assert(I.EncData[0] = $80);
  1359. Assert(I.EncData[1] = $02);
  1360. Assert(pbVarIntToUInt32(I) = $100);
  1361. pbVarIntInitUInt32(I, $3FFF);
  1362. Assert(I.EncSize = 2);
  1363. Assert(I.EncData[0] = $FF);
  1364. Assert(I.EncData[1] = $7F);
  1365. Assert(pbVarIntToUInt32(I) = $3FFF);
  1366. pbVarIntInitUInt32(I, $4000);
  1367. Assert(I.EncSize = 3);
  1368. Assert(I.EncData[0] = $80);
  1369. Assert(I.EncData[1] = $80);
  1370. Assert(I.EncData[2] = $01);
  1371. Assert(pbVarIntToUInt32(I) = $4000);
  1372. pbVarIntInitUInt32(I, $4001);
  1373. Assert(I.EncSize = 3);
  1374. Assert(I.EncData[0] = $81);
  1375. Assert(I.EncData[1] = $80);
  1376. Assert(I.EncData[2] = $01);
  1377. Assert(pbVarIntToUInt32(I) = $4001);
  1378. pbVarIntInitUInt32(I, $1FFFFF);
  1379. Assert(I.EncSize = 3);
  1380. Assert(I.EncData[0] = $FF);
  1381. Assert(I.EncData[1] = $FF);
  1382. Assert(I.EncData[2] = $7F);
  1383. Assert(pbVarIntToUInt32(I) = $1FFFFF);
  1384. pbVarIntInitUInt32(I, $200000);
  1385. Assert(I.EncSize = 4);
  1386. Assert(I.EncData[0] = $80);
  1387. Assert(I.EncData[1] = $80);
  1388. Assert(I.EncData[2] = $80);
  1389. Assert(I.EncData[3] = $01);
  1390. Assert(pbVarIntToUInt32(I) = $200000);
  1391. pbVarIntInitUInt32(I, $FFFFFFF);
  1392. Assert(I.EncSize = 4);
  1393. Assert(I.EncData[0] = $FF);
  1394. Assert(I.EncData[1] = $FF);
  1395. Assert(I.EncData[2] = $FF);
  1396. Assert(I.EncData[3] = $7F);
  1397. Assert(pbVarIntToUInt32(I) = $FFFFFFF);
  1398. pbVarIntInitUInt32(I, $10000000);
  1399. Assert(I.EncSize = 5);
  1400. Assert(I.EncData[0] = $80);
  1401. Assert(I.EncData[1] = $80);
  1402. Assert(I.EncData[2] = $80);
  1403. Assert(I.EncData[3] = $80);
  1404. Assert(I.EncData[4] = $01);
  1405. Assert(pbVarIntToUInt32(I) = $10000000);
  1406. pbVarIntInitUInt32(I, $12345678);
  1407. Assert(I.EncSize = 5);
  1408. Assert(I.EncData[0] = $F8);
  1409. Assert(I.EncData[1] = $AC);
  1410. Assert(I.EncData[2] = $D1);
  1411. Assert(I.EncData[3] = $91);
  1412. Assert(I.EncData[4] = $01);
  1413. Assert(pbVarIntToUInt32(I) = $12345678);
  1414. pbVarIntInitUInt32(I, $FFFFFFFF);
  1415. Assert(I.EncSize = 5);
  1416. Assert(I.EncData[0] = $FF);
  1417. Assert(I.EncData[1] = $FF);
  1418. Assert(I.EncData[2] = $FF);
  1419. Assert(I.EncData[3] = $FF);
  1420. Assert(I.EncData[4] = $0F);
  1421. Assert(pbVarIntToUInt32(I) = $FFFFFFFF);
  1422. // pbVarIntInitBinBuf
  1423. A := 0;
  1424. pbVarIntInitBinBuf(I, A, SizeOf(A));
  1425. Assert(I.EncSize = 1);
  1426. Assert(I.EncData[0] = 0);
  1427. Assert(pbVarIntToUInt32(I) = 0);
  1428. A := 1;
  1429. pbVarIntInitBinBuf(I, A, SizeOf(A));
  1430. Assert(I.EncSize = 1);
  1431. Assert(I.EncData[0] = 1);
  1432. Assert(pbVarIntToUInt32(I) = 1);
  1433. A := $7F;
  1434. pbVarIntInitBinBuf(I, A, SizeOf(A));
  1435. Assert(I.EncSize = 1);
  1436. Assert(I.EncData[0] = $7F);
  1437. Assert(pbVarIntToUInt32(I) = $7F);
  1438. A := $80;
  1439. pbVarIntInitBinBuf(I, A, SizeOf(A));
  1440. Assert(I.EncSize = 2);
  1441. Assert(I.EncData[0] = $80);
  1442. Assert(I.EncData[1] = $01);
  1443. Assert(pbVarIntToUInt32(I) = $80);
  1444. A := $81;
  1445. pbVarIntInitBinBuf(I, A, SizeOf(A));
  1446. Assert(I.EncSize = 2);
  1447. Assert(I.EncData[0] = $81);
  1448. Assert(I.EncData[1] = $01);
  1449. Assert(pbVarIntToUInt32(I) = $81);
  1450. A := $100;
  1451. pbVarIntInitBinBuf(I, A, SizeOf(A));
  1452. Assert(I.EncSize = 2);
  1453. Assert(I.EncData[0] = $80);
  1454. Assert(I.EncData[1] = $02);
  1455. Assert(pbVarIntToUInt32(I) = $100);
  1456. A := $3FFF;
  1457. pbVarIntInitBinBuf(I, A, SizeOf(A));
  1458. Assert(I.EncSize = 2);
  1459. Assert(I.EncData[0] = $FF);
  1460. Assert(I.EncData[1] = $7F);
  1461. Assert(pbVarIntToUInt32(I) = $3FFF);
  1462. A := $4000;
  1463. pbVarIntInitBinBuf(I, A, SizeOf(A));
  1464. Assert(I.EncSize = 3);
  1465. Assert(I.EncData[0] = $80);
  1466. Assert(I.EncData[1] = $80);
  1467. Assert(I.EncData[2] = $01);
  1468. Assert(pbVarIntToUInt32(I) = $4000);
  1469. A := $4001;
  1470. pbVarIntInitBinBuf(I, A, SizeOf(A));
  1471. Assert(I.EncSize = 3);
  1472. Assert(I.EncData[0] = $81);
  1473. Assert(I.EncData[1] = $80);
  1474. Assert(I.EncData[2] = $01);
  1475. Assert(pbVarIntToUInt32(I) = $4001);
  1476. A := $200000;
  1477. pbVarIntInitBinBuf(I, A, SizeOf(A));
  1478. Assert(I.EncSize = 4);
  1479. Assert(I.EncData[0] = $80);
  1480. Assert(I.EncData[1] = $80);
  1481. Assert(I.EncData[2] = $80);
  1482. Assert(I.EncData[3] = $01);
  1483. Assert(pbVarIntToUInt32(I) = $200000);
  1484. A := $10000000;
  1485. pbVarIntInitBinBuf(I, A, SizeOf(A));
  1486. Assert(I.EncSize = 5);
  1487. Assert(I.EncData[0] = $80);
  1488. Assert(I.EncData[1] = $80);
  1489. Assert(I.EncData[2] = $80);
  1490. Assert(I.EncData[3] = $80);
  1491. Assert(I.EncData[4] = $01);
  1492. Assert(pbVarIntToUInt32(I) = $10000000);
  1493. A := $12345678;
  1494. pbVarIntInitBinBuf(I, A, SizeOf(A));
  1495. Assert(I.EncSize = 5);
  1496. Assert(I.EncData[0] = $F8);
  1497. Assert(I.EncData[1] = $AC);
  1498. Assert(I.EncData[2] = $D1);
  1499. Assert(I.EncData[3] = $91);
  1500. Assert(I.EncData[4] = $01);
  1501. Assert(pbVarIntToUInt32(I) = $12345678);
  1502. A := $FFFFFFFF;
  1503. pbVarIntInitBinBuf(I, A, SizeOf(A));
  1504. Assert(I.EncSize = 5);
  1505. Assert(I.EncData[0] = $FF);
  1506. Assert(I.EncData[1] = $FF);
  1507. Assert(I.EncData[2] = $FF);
  1508. Assert(I.EncData[3] = $FF);
  1509. Assert(I.EncData[4] = $0F);
  1510. Assert(pbVarIntToUInt32(I) = $FFFFFFFF);
  1511. // pbVarIntInitEncBuf
  1512. pbVarIntInitUInt32(I, 0);
  1513. Assert(pbVarIntInitEncBuf(J, I.EncData[0], SizeOf(I.EncData)) = I.EncSize);
  1514. Assert(pbVarIntToUInt32(J) = 0);
  1515. pbVarIntInitUInt32(I, 1);
  1516. Assert(pbVarIntInitEncBuf(J, I.EncData[0], SizeOf(I.EncData)) = I.EncSize);
  1517. Assert(pbVarIntToUInt32(J) = 1);
  1518. pbVarIntInitUInt32(I, $80);
  1519. Assert(pbVarIntInitEncBuf(J, I.EncData[0], SizeOf(I.EncData)) = I.EncSize);
  1520. Assert(pbVarIntToUInt32(J) = $80);
  1521. pbVarIntInitUInt32(I, $3FFF);
  1522. Assert(pbVarIntInitEncBuf(J, I.EncData[0], SizeOf(I.EncData)) = I.EncSize);
  1523. Assert(pbVarIntToUInt32(J) = $3FFF);
  1524. pbVarIntInitUInt32(I, $4000);
  1525. Assert(pbVarIntInitEncBuf(J, I.EncData[0], SizeOf(I.EncData)) = I.EncSize);
  1526. Assert(pbVarIntToUInt32(J) = $4000);
  1527. pbVarIntInitUInt32(I, $4001);
  1528. Assert(pbVarIntInitEncBuf(J, I.EncData[0], SizeOf(I.EncData)) = I.EncSize);
  1529. Assert(pbVarIntToUInt32(J) = $4001);
  1530. pbVarIntInitUInt32(I, $12345678);
  1531. Assert(pbVarIntInitEncBuf(J, I.EncData[0], SizeOf(I.EncData)) = I.EncSize);
  1532. Assert(pbVarIntToUInt32(J) = $12345678);
  1533. pbVarIntInitUInt32(I, $FFFFFFFF);
  1534. Assert(pbVarIntInitEncBuf(J, I.EncData[0], SizeOf(I.EncData)) = I.EncSize);
  1535. Assert(pbVarIntToUInt32(J) = $FFFFFFFF);
  1536. // pbVarIntToBinBuf
  1537. pbVarIntInitUInt32(I, 0);
  1538. pbVarIntToBinBuf(I, A, SizeOf(A));
  1539. Assert(A = 0);
  1540. pbVarIntInitUInt32(I, 1);
  1541. pbVarIntToBinBuf(I, A, SizeOf(A));
  1542. Assert(A = 1);
  1543. pbVarIntInitUInt32(I, $7F);
  1544. pbVarIntToBinBuf(I, A, SizeOf(A));
  1545. Assert(A = $7F);
  1546. pbVarIntInitUInt32(I, $80);
  1547. pbVarIntToBinBuf(I, A, SizeOf(A));
  1548. Assert(A = $80);
  1549. pbVarIntInitUInt32(I, $81);
  1550. pbVarIntToBinBuf(I, A, SizeOf(A));
  1551. Assert(A = $81);
  1552. pbVarIntInitUInt32(I, $3FFF);
  1553. pbVarIntToBinBuf(I, A, SizeOf(A));
  1554. Assert(A = $3FFF);
  1555. pbVarIntInitUInt32(I, $4000);
  1556. pbVarIntToBinBuf(I, A, SizeOf(A));
  1557. Assert(A = $4000);
  1558. pbVarIntInitUInt32(I, $4001);
  1559. pbVarIntToBinBuf(I, A, SizeOf(A));
  1560. Assert(A = $4001);
  1561. pbVarIntInitUInt32(I, $200000);
  1562. pbVarIntToBinBuf(I, A, SizeOf(A));
  1563. Assert(A = $200000);
  1564. pbVarIntInitUInt32(I, $10000000);
  1565. pbVarIntToBinBuf(I, A, SizeOf(A));
  1566. Assert(A = $10000000);
  1567. pbVarIntInitUInt32(I, $12345678);
  1568. pbVarIntToBinBuf(I, A, SizeOf(A));
  1569. Assert(A = $12345678);
  1570. pbVarIntInitUInt32(I, $FFFFFFFF);
  1571. pbVarIntToBinBuf(I, A, SizeOf(A));
  1572. Assert(A = $FFFFFFFF);
  1573. // pbSInt32ToUInt32
  1574. Assert(pbSInt32ToUInt32(0) = 0);
  1575. Assert(pbSInt32ToUInt32(-1) = 1);
  1576. Assert(pbSInt32ToUInt32(1) = 2);
  1577. Assert(pbSInt32ToUInt32(-2) = 3);
  1578. Assert(pbSInt32ToUInt32(2) = 4);
  1579. Assert(pbSInt32ToUInt32(-3) = 5);
  1580. Assert(pbSInt32ToUInt32(2147483647) = $FFFFFFFE);
  1581. Assert(pbSInt32ToUInt32(-2147483648) = $FFFFFFFF);
  1582. // pbUInt32ToSInt32
  1583. Assert(pbUInt32ToSInt32(0) = 0);
  1584. Assert(pbUInt32ToSInt32(1) = -1);
  1585. Assert(pbUInt32ToSInt32(2) = 1);
  1586. Assert(pbUInt32ToSInt32(3) = -2);
  1587. Assert(pbUInt32ToSInt32(4) = 2);
  1588. Assert(pbUInt32ToSInt32(5) = -3);
  1589. Assert(pbUInt32ToSInt32($FFFFFFFE) = 2147483647);
  1590. Assert(pbUInt32ToSInt32($FFFFFFFF) = -2147483648);
  1591. // pbVarIntInitSInt32
  1592. pbVarIntInitSInt32(I, 0);
  1593. Assert(pbVarIntToSInt32(I) = 0);
  1594. pbVarIntInitSInt32(I, -1);
  1595. Assert(pbVarIntToSInt32(I) = -1);
  1596. pbVarIntInitSInt32(I, 1);
  1597. Assert(pbVarIntToSInt32(I) = 1);
  1598. pbVarIntInitSInt32(I, 2147483647);
  1599. Assert(pbVarIntToSInt32(I) = 2147483647);
  1600. pbVarIntInitSInt32(I, -2147483648);
  1601. Assert(pbVarIntToSInt32(I) = -2147483648);
  1602. // pbSInt64ToUInt64
  1603. Assert(pbSInt64ToUInt64(0) = 0);
  1604. Assert(pbSInt64ToUInt64(-1) = 1);
  1605. Assert(pbSInt64ToUInt64(1) = 2);
  1606. Assert(pbSInt64ToUInt64(-2) = 3);
  1607. Assert(pbSInt64ToUInt64(2) = 4);
  1608. Assert(pbSInt64ToUInt64(-3) = 5);
  1609. Assert(pbSInt64ToUInt64(2147483647) = $FFFFFFFE);
  1610. Assert(pbSInt64ToUInt64(-2147483648) = $FFFFFFFF);
  1611. Assert(pbSInt64ToUInt64(2147483648) = $100000000);
  1612. Assert(pbSInt64ToUInt64(-2147483649) = $100000001);
  1613. Assert(pbSInt64ToUInt64(4611686018427387903) = $7FFFFFFFFFFFFFFE);
  1614. Assert(pbSInt64ToUInt64(-4611686018427387904) = $7FFFFFFFFFFFFFFF);
  1615. Assert(pbSInt64ToUInt64(4611686018427387904) = $8000000000000000);
  1616. Assert(pbSInt64ToUInt64(-4611686018427387905) = $8000000000000001);
  1617. Assert(pbSInt64ToUInt64(9223372036854775807) = $FFFFFFFFFFFFFFFE);
  1618. Assert(pbSInt64ToUInt64(-9223372036854775808) = $FFFFFFFFFFFFFFFF);
  1619. // pbUInt64ToSInt64
  1620. Assert(pbUInt64ToSInt64(0) = 0);
  1621. Assert(pbUInt64ToSInt64(1) = -1);
  1622. Assert(pbUInt64ToSInt64(2) = 1);
  1623. Assert(pbUInt64ToSInt64(3) = -2);
  1624. Assert(pbUInt64ToSInt64(4) = 2);
  1625. Assert(pbUInt64ToSInt64(5) = -3);
  1626. Assert(pbUInt64ToSInt64($FFFFFFFE) = 2147483647);
  1627. Assert(pbUInt64ToSInt64($FFFFFFFF) = -2147483648);
  1628. Assert(pbUInt64ToSInt64($100000000) = 2147483648);
  1629. Assert(pbUInt64ToSInt64($100000001) = -2147483649);
  1630. Assert(pbUInt64ToSInt64($7FFFFFFFFFFFFFFE) = 4611686018427387903);
  1631. Assert(pbUInt64ToSInt64($7FFFFFFFFFFFFFFF) = -4611686018427387904);
  1632. Assert(pbUInt64ToSInt64($8000000000000000) = 4611686018427387904);
  1633. Assert(pbUInt64ToSInt64($8000000000000001) = -4611686018427387905);
  1634. Assert(pbUInt64ToSInt64($FFFFFFFFFFFFFFFE) = 9223372036854775807);
  1635. Assert(pbUInt64ToSInt64($FFFFFFFFFFFFFFFF) = -9223372036854775808);
  1636. // pbVarIntInitSInt64
  1637. pbVarIntInitSInt64(I, 0);
  1638. Assert(pbVarIntToSInt64(I) = 0);
  1639. pbVarIntInitSInt64(I, -1);
  1640. Assert(pbVarIntToSInt64(I) = -1);
  1641. pbVarIntInitSInt64(I, 1);
  1642. Assert(pbVarIntToSInt64(I) = 1);
  1643. pbVarIntInitSInt64(I, 2147483647);
  1644. Assert(pbVarIntToSInt64(I) = 2147483647);
  1645. pbVarIntInitSInt64(I, -2147483648);
  1646. Assert(pbVarIntToSInt64(I) = -2147483648);
  1647. pbVarIntInitSInt64(I, 2147483648);
  1648. Assert(pbVarIntToSInt64(I) = 2147483648);
  1649. pbVarIntInitSInt64(I, -2147483649);
  1650. Assert(pbVarIntToSInt64(I) = -2147483649);
  1651. pbVarIntInitSInt64(I, 9223372036854775807);
  1652. Assert(pbVarIntToSInt64(I) = 9223372036854775807);
  1653. pbVarIntInitSInt64(I, -9223372036854775808);
  1654. Assert(pbVarIntToSInt64(I) = -9223372036854775808);
  1655. end;
  1656. procedure SelfTest_Encode;
  1657. var
  1658. B : array[0..1023] of Byte;
  1659. begin
  1660. FillChar(B, SizeOf(B), 0);
  1661. Assert(pbEncodeFieldKey(B[0], SizeOf(B), 3, pwtVarBytes) = 1);
  1662. Assert(B[0] = $1A);
  1663. Assert(pbEncodeFieldString(B[0], SizeOf(B), 2, 'testing') = 9);
  1664. Assert(B[0] = $12);
  1665. Assert(B[1] = $07);
  1666. Assert(B[2] = $74);
  1667. Assert(B[8] = $67);
  1668. Assert(pbEncodeFieldUInt32(B[0], SizeOf(B), 2, 12) = 2);
  1669. Assert(B[0] = $10);
  1670. Assert(B[1] = $0C);
  1671. FillChar(B, SizeOf(B), 0);
  1672. Assert(pbEncodeFieldString(B[0], 0, 2, 'testing') = 9);
  1673. Assert(B[0] = 0);
  1674. Assert(B[1] = 0);
  1675. Assert(B[2] = 0);
  1676. Assert(B[8] = 0);
  1677. Assert(pbEncodeFieldUInt32(B[0], 0, 2, 12) = 2);
  1678. Assert(B[0] = 0);
  1679. Assert(B[1] = 0);
  1680. end;
  1681. procedure SelfTest_Decode_CallbackProc(const Field: TpbProtoBufDecodeField; const Data: Pointer);
  1682. var
  1683. A : LongWord;
  1684. B : Int64;
  1685. C : AnsiString;
  1686. begin
  1687. case Integer(Data) of
  1688. 1 : case Field.FieldNum of
  1689. 4 : begin
  1690. Assert(Field.WireType = pwtVarInt);
  1691. Assert(pbVarIntToUInt32(Field.ValueVarInt) = 13);
  1692. A := 0;
  1693. pbDecodeFieldUInt32(Field, A);
  1694. Assert(A = 13);
  1695. end;
  1696. 5 : begin
  1697. Assert(Field.WireType = pwtVarInt);
  1698. Assert(pbVarIntToSInt64(Field.ValueVarInt) = -1);
  1699. B := 0;
  1700. pbDecodeFieldSInt64(Field, B);
  1701. Assert(B = -1);
  1702. end;
  1703. 6 : begin
  1704. Assert(Field.WireType = pwtVarBytes);
  1705. pbDecodeFieldString(Field, C);
  1706. Assert(C = 'ABC');
  1707. end;
  1708. else
  1709. Assert(False);
  1710. end;
  1711. else
  1712. Assert(False);
  1713. end;
  1714. end;
  1715. procedure SelfTest_Decode;
  1716. var
  1717. B : array[0..1023] of Byte;
  1718. P : PByte;
  1719. L, N : Integer;
  1720. begin
  1721. P := @B[0];
  1722. L := SizeOf(B);
  1723. N := pbEncodeFieldInt32(P^, L, 4, 13);
  1724. Dec(L, N);
  1725. Inc(P, N);
  1726. N := pbEncodeFieldSInt64(P^, L, 5, -1);
  1727. Dec(L, N);
  1728. Inc(P, N);
  1729. N := pbEncodeFieldString(P^, L, 6, 'ABC');
  1730. Dec(L, N);
  1731. pbDecodeProtoBuf(B[0], SizeOf(B) - L, SelfTest_Decode_CallbackProc, Ptr(1));
  1732. end;
  1733. procedure SelfTest;
  1734. begin
  1735. SelfTest_VarInt;
  1736. SelfTest_Encode;
  1737. SelfTest_Decode;
  1738. end;
  1739. {$ENDIF}
  1740. end.