uSOTools.pas 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. unit uSOTools;
  2. interface
  3. uses
  4. superobject, SysUtils, Classes, Variants;
  5. type
  6. TSOTools = class(TObject)
  7. public
  8. /// <summary>
  9. /// 产生一个Hash值
  10. /// QDAC群主的Hash函数
  11. /// </summary>
  12. class function hashOf(const p:Pointer;l:Integer): Integer;overload;
  13. /// <summary>
  14. /// 产生一个Hash值
  15. /// </summary>
  16. class function hashOf(const vStrData:String): Integer; overload;
  17. /// <summary>
  18. /// 从文件中解析
  19. /// </summary>
  20. class function JsnParseFromFile(pvFile: string): ISuperObject;
  21. /// <summary>
  22. /// 将pvData数据保存到文件中
  23. /// </summary>
  24. class function JsnSaveToFile(pvData: ISuperObject; pvFile: string): Boolean;
  25. /// <summary>
  26. /// 保留能作为命名的字符
  27. /// </summary>
  28. class function clearAvalidIDChar(pvStringData: string): String;
  29. /// <summary>
  30. /// 删除一些字符
  31. /// </summary>
  32. class function DeleteChars(const s: string; pvCharSets: TSysCharSet): string;
  33. /// <summary>
  34. /// 制作一个JSonKey
  35. /// </summary>
  36. class function makeMapKey(pvStringData: string): String;
  37. end;
  38. implementation
  39. class function TSOTools.clearAvalidIDChar(pvStringData: string): String;
  40. var
  41. i, l, r: Integer;
  42. lvStr: string;
  43. begin
  44. Result := '';
  45. l := Length(pvStringData);
  46. if l = 0 then exit;
  47. SetLength(lvStr, l);
  48. r := 0;
  49. for i := 2 to l do
  50. begin
  51. if r = 0 then
  52. begin // 第一个字符为字母或者下画线
  53. if pvStringData[i] in ['_', 'a'..'z', 'A'..'Z'] then
  54. begin
  55. inc(r);
  56. lvStr[r] := pvStringData[i];
  57. end;
  58. end else if pvStringData[i] in ['_', 'a'..'z', 'A'..'Z', '0'..'9'] then
  59. begin
  60. inc(r);
  61. lvStr[r] := pvStringData[i];
  62. end;
  63. end;
  64. if r > 0 then
  65. begin
  66. SetLength(lvStr, r);
  67. Result := lvStr;
  68. end;
  69. end;
  70. // 字符长度:3.8M 15ns
  71. // 字符长度:38.15 M 391ns
  72. // DeleteChars(pvGUIDKey, ['-', '{','}']);
  73. class function TSOTools.DeleteChars(const s: string; pvCharSets: TSysCharSet):
  74. string;
  75. var
  76. i, l, times: Integer;
  77. lvStr: string;
  78. begin
  79. l := Length(s);
  80. SetLength(lvStr, l);
  81. times := 0;
  82. for i := 1 to l do
  83. begin
  84. if not (s[i] in pvCharSets) then
  85. begin
  86. inc(times);
  87. lvStr[times] := s[i];
  88. end;
  89. end;
  90. SetLength(lvStr, times);
  91. Result := lvStr;
  92. end;
  93. class function TSOTools.hashOf(const vStrData:String): Integer;
  94. var
  95. lvStr:AnsiString;
  96. begin
  97. lvStr := AnsiString(vStrData);
  98. Result := hashOf(PAnsiChar(lvStr), Length(lvStr));
  99. end;
  100. class function TSOTools.hashOf(const p:Pointer;l:Integer): Integer;
  101. var
  102. ps:PInteger;
  103. lr:Integer;
  104. begin
  105. Result:=0;
  106. if l>0 then
  107. begin
  108. ps:=p;
  109. lr:=(l and $03);//检查长度是否为4的整数倍
  110. l:=(l and $FFFFFFFC);//整数长度
  111. while l>0 do
  112. begin
  113. Result:=((Result shl 5) or (Result shr 27)) xor ps^;
  114. Inc(ps);
  115. Dec(l,4);
  116. end;
  117. if lr<>0 then
  118. begin
  119. l:=0;
  120. Move(ps^,l,lr);
  121. Result:=((Result shl 5) or (Result shr 27)) xor l;
  122. end;
  123. end;
  124. end;
  125. class function TSOTools.JsnParseFromFile(pvFile: string): ISuperObject;
  126. var
  127. lvStream: TMemoryStream;
  128. lvStr: AnsiString;
  129. begin
  130. Result := nil;
  131. if FileExists(pvFile) then
  132. begin
  133. lvStream := TMemoryStream.Create;
  134. try
  135. lvStream.LoadFromFile(pvFile);
  136. lvStream.Position := 0;
  137. SetLength(lvStr, lvStream.Size);
  138. lvStream.ReadBuffer(lvStr[1], lvStream.Size);
  139. Result := SO(String(lvStr));
  140. finally
  141. lvStream.Free;
  142. end;
  143. end;
  144. if Result <> nil then
  145. if not (Result.DataType in [stArray, stObject]) then
  146. Result := nil;
  147. end;
  148. class function TSOTools.JsnSaveToFile(pvData: ISuperObject; pvFile: string):
  149. Boolean;
  150. var
  151. lvStream: TMemoryStream;
  152. lvStr: AnsiString;
  153. begin
  154. Result := false;
  155. if pvData = nil then exit;
  156. lvStream := TMemoryStream.Create;
  157. try
  158. lvStr :=AnsiString(pvData.AsJSon(True, False));
  159. if lvStr <> '' then
  160. lvStream.WriteBuffer(lvStr[1], Length(lvStr));
  161. lvStream.SaveToFile(pvFile);
  162. Result := true;
  163. finally
  164. lvStream.Free;
  165. end;
  166. end;
  167. class function TSOTools.makeMapKey(pvStringData: string): String;
  168. var
  169. lvCheckCanKey:Boolean;
  170. lvMapKey:AnsiString;
  171. i:Integer;
  172. begin
  173. Result := '';
  174. lvMapKey :=AnsiString(Trim(LowerCase(pvStringData)));
  175. if lvMapKey = '' then exit;
  176. lvCheckCanKey := True;
  177. if Length(lvMapKey) = 0 then
  178. begin
  179. Result := 'null';
  180. end else if Length(lvMapKey) > 1 then
  181. begin
  182. lvCheckCanKey := lvMapKey[1] in ['a'..'z','0'..'9', '_'];
  183. if lvCheckCanKey then
  184. begin
  185. //判断是否可以做JSON主键
  186. for I := 2 to Length(lvMapKey) do
  187. begin
  188. if not (lvMapKey[i] in ['a'..'z','0'..'9', '_', '-']) then
  189. begin
  190. lvCheckCanKey := false;
  191. Break;
  192. end;
  193. end;
  194. end;
  195. end else
  196. begin
  197. lvCheckCanKey := lvMapKey[1] in ['a'..'z','0'..'9', '_'];
  198. end;
  199. if lvCheckCanKey then
  200. begin
  201. Result := String(lvMapKey);
  202. end else
  203. begin
  204. //使用hash值
  205. Result := '_' + IntToStr(TSuperAvlEntry.Hash(pvStringData));
  206. end;
  207. end;
  208. end.