varutils.inc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2001 by the Free Pascal development team
  5. Variant routines for non-windows oses.
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {$ifdef HASVARIANT}
  13. { ---------------------------------------------------------------------
  14. Some general stuff: Error handling and so on.
  15. ---------------------------------------------------------------------}
  16. Procedure SetUnlockResult (P : PVarArray; Res : HResult);
  17. begin
  18. If Res=VAR_OK then
  19. Res:=SafeArrayUnlock(P)
  20. else
  21. SafeArrayUnlock(P);
  22. end;
  23. Procedure MakeWideString (Var P : PWideChar; W : WideString);
  24. begin
  25. P:=PWideChar(W);
  26. end;
  27. Procedure CopyAsWideString (Var PDest : PWideChar; PSource : PWideChar);
  28. begin
  29. PDest:=PWideChar(WideString(PSource));
  30. end;
  31. { ---------------------------------------------------------------------
  32. Basic variant handling.
  33. ---------------------------------------------------------------------}
  34. function VariantInit(var Varg: TVarData): HRESULT;stdcall;
  35. begin
  36. With Varg do
  37. begin
  38. VType:=varEmpty;
  39. FillChar(VBytes, SizeOf(VBytes), 0);
  40. end;
  41. Result:=VAR_OK;
  42. end;
  43. function VariantClear(var Varg: TVarData): HRESULT;stdcall;
  44. begin
  45. With Varg do
  46. if (VType and varArray)=varArray then
  47. begin
  48. Exit(SafeArrayDestroy(VArray))
  49. end
  50. else
  51. begin
  52. if (VType and varByRef) = 0 then
  53. case VType of
  54. varEmpty, varNull, varSmallint, varInteger, varSingle, varDouble,
  55. varCurrency, varDate, varError, varBoolean, varByte,VarShortInt,
  56. varInt64, VarLongWord,VarQWord:;
  57. varOleStr:
  58. WideString(Pointer(VOleStr)):='';
  59. varDispatch,
  60. varUnknown:
  61. NoInterfaces;
  62. else
  63. exit(VAR_BADVARTYPE)
  64. end;
  65. end;
  66. Result:=VariantInit(Varg);
  67. end;
  68. function VariantCopy(var VargDest: TVarData; const VargSrc: TVarData): HRESULT;stdcall;
  69. begin
  70. if @VargSrc = @VargDest then
  71. Exit(VAR_OK);
  72. Result:=VariantClear(VargDest);
  73. if Result<>VAR_OK then
  74. exit;
  75. With VargSrc do
  76. begin
  77. if (VType and varArray) <> 0 then
  78. Result:=SafeArrayCopy(VArray,VargDest.VArray)
  79. else
  80. begin
  81. if (VType and varByRef) <> 0 then
  82. VArgDest.VPointer:=VPointer
  83. else
  84. case (VType and varTypeMask) of
  85. varEmpty, varNull:;
  86. varSmallint, varInteger, varSingle, varDouble, varCurrency,
  87. varDate, varError, varBoolean, varByte,VarShortInt,
  88. varInt64, VarLongWord,VarQWord:
  89. Move(VBytes, VargDest.VBytes, SizeOf(VargDest.VBytes));
  90. varOleStr:
  91. CopyAsWideString(VargDest.VOleStr,VOleStr);
  92. varDispatch,
  93. varUnknown:
  94. NoInterfaces; // We should bump up reference count here (Addref)
  95. else
  96. Exit(VAR_BADVARTYPE);
  97. end;
  98. end;
  99. VargDest.VType:=VType;
  100. end;
  101. end;
  102. function VariantCopyInd(var VargDest: TVarData; const VargSrc: TVarData): HRESULT;stdcall;
  103. begin
  104. if (VargSrc.VType and varByRef) = 0 then
  105. Exit(VariantCopy(VargDest, VargSrc));
  106. With VargSrc do
  107. begin
  108. if (VType and varArray) <> 0 then
  109. Exit(VAR_INVALIDARG);
  110. case (VType and varTypeMask) of
  111. varEmpty, varNull:;
  112. varSmallint : VargDest.VSmallInt:=PSmallInt(VPointer)^;
  113. varInteger : VargDest.VInteger:=PLongint(VPointer)^;
  114. varSingle : VargDest.VSingle:=PSingle(VPointer)^;
  115. varDouble : VargDest.VDouble:=PDouble(VPointer)^;
  116. varCurrency : VargDest.VCurrency:=PCurrency(VPointer)^;
  117. varDate : VargDest.VDate:=PDate(VPointer)^;
  118. varBoolean : VargDest.VBoolean:=PWordBool(VPointer)^;
  119. varError : VargDest.VError:=PError(VPointer)^;
  120. varByte : VargDest.VByte:=PByte(VPointer)^;
  121. VarShortInt : VargDest.VShortInt:=PShortInt(VPointer)^;
  122. VarInt64 : VargDest.VInt64:=PInt64(VPointer)^;
  123. VarLongWord : VargDest.VLongWord:=PCardinal(VPointer)^;
  124. VarQWord : VargDest.VQWord:=PQWord(VPointer)^;
  125. varVariant : Variant(VargDest):=Variant(PVarData(VPointer)^);
  126. varOleStr : CopyAsWideString(VargDest.VOleStr,PVarData(VPointer)^.VoleStr);
  127. varDispatch,
  128. varUnknown : NoInterfaces;
  129. else
  130. Exit(VAR_BADVARTYPE);
  131. end;
  132. VargDest.VType:=VType and VarTypeMask;
  133. end;
  134. Result:=VAR_OK;
  135. end;
  136. Function VariantChangeTypeEx(var VargDest: TVarData; const VargSrc: TVarData;
  137. LCID: Integer; Flags: Word; VarType: Word): HRESULT; stdcall;
  138. var
  139. Tmp : TVarData;
  140. begin
  141. if ((VarType and varArray) <> 0) or
  142. ((VargSrc.VType and varArray) <> 0) or
  143. ((VarType and varByRef) <> 0) then
  144. Exit(VAR_INVALIDARG);
  145. Result:=VariantCopyInd(Tmp, VargSrc);
  146. if Result = VAR_OK then
  147. try
  148. Result:=VariantClear(VargDest);
  149. {$RANGECHECKS ON}
  150. if Result = VAR_OK then
  151. try
  152. case Vartype of
  153. varSmallInt : VargDest.VSmallInt:=VariantToSmallInt(Tmp);
  154. varInteger : VargDest.VInteger:=VariantToLongint(Tmp);
  155. varSingle : VargDest.VSingle:=VariantToSingle(Tmp);
  156. varDouble : VargDest.VDouble:=VariantToDouble(Tmp);
  157. varCurrency : VargDest.VCurrency:=VariantToCurrency(Tmp);
  158. varDate : VargDest.VDate:=VariantToDate(tmp);
  159. varOleStr : MakeWideString(VargDest.VoleStr, VariantToWideString(tmp));
  160. varDispatch : Result:=VAR_TYPEMISMATCH;
  161. varUnknown : Result:=VAR_TYPEMISMATCH;
  162. varBoolean : VargDest.VBoolean:=VariantToBoolean(Tmp);
  163. varByte : VargDest.VByte:=VariantToByte(Tmp);
  164. VarShortInt : VargDest.VShortInt:=VariantToShortInt(Tmp);
  165. VarInt64 : VargDest.Vint64:=VariantToInt64(Tmp);
  166. VarLongWord : VargDest.VLongWord:=VariantToCardinal(Tmp);
  167. VarQWord : VargDest.VQWord:=VariantToQword(tmp);
  168. else
  169. Result:=VAR_BADVARTYPE;
  170. end;
  171. If Result = VAR_OK then
  172. VargDest.VType:=VarType;
  173. except
  174. On E : EVariantError do
  175. Result:=E.ErrCode;
  176. else
  177. Result:=VAR_INVALIDARG;
  178. end;
  179. finally
  180. VariantClear(Tmp);
  181. end;
  182. end;
  183. { ---------------------------------------------------------------------
  184. Variant array support
  185. ---------------------------------------------------------------------}
  186. Function CheckArrayUnlocked (psa : PVarArray) : HResult;
  187. begin
  188. If psa^.LockCount = 0 Then
  189. Result:=VAR_OK
  190. else
  191. Result:=VAR_ARRAYISLOCKED;
  192. end;
  193. Function CheckVarArray(psa: PVarArray ): HRESULT;
  194. begin
  195. If psa=nil then
  196. Result:=VAR_INVALIDARG
  197. else
  198. Result:=VAR_OK;
  199. end;
  200. Function SafeArrayCalculateElementAddress(psa: PVarArray; aElement: Integer): Pointer;
  201. begin
  202. Result:=Pointer(Integer(psa^.Data)+(aElement*psa^.ElementSize));
  203. end;
  204. Function CheckVarArrayAndCalculateAddress(psa: PVarArray;
  205. Indices: PVarArrayCoorArray; var Address: Pointer; Lockit: Boolean): HRESULT;
  206. Function CountElements(D: Longint): Longint;
  207. begin
  208. if (D<psa^.DimCount) then
  209. Result:=CountElements(D+1)+psa^.Bounds[D-1].ElementCount
  210. else
  211. Result:=1;
  212. end;
  213. var
  214. LB,HB,I,Count : LongInt;
  215. begin
  216. Result:=CheckVarArray(psa);
  217. Address:=nil;
  218. Count:=0;
  219. If Result<>VAR_OK then
  220. exit;
  221. for I:=1 to psa^.DimCount do
  222. begin
  223. LB:=psa^.Bounds[I-1].LowBound;
  224. HB:=LB+psa^.Bounds[I-1].ElementCount;
  225. if (LB=HB) or ((Indices^[I-1]< LB) or(Indices^[I-1]>HB)) then
  226. Exit(VAR_BADINDEX);
  227. Count:=Count+(Indices^[I-1]-LB)*CountElements(I+1);
  228. end;
  229. Address:=SafeArrayCalculateElementAddress(psa, Count);
  230. if LockIt then
  231. Result:=SafeArrayLock(psa);
  232. end;
  233. Function SafeArrayElementTotal(psa: PVarArray): Integer;
  234. var
  235. I: Integer;
  236. begin
  237. Result:=1;
  238. With psa^ do
  239. for I:=0 to DimCount - 1 do
  240. Result:=Result*Bounds[I].ElementCount;
  241. end;
  242. type
  243. TVariantArrayType = (vatNormal, varInterface, varWideString);
  244. Function VariantArrayType(psa: PVarArray): TVariantArrayType;
  245. begin
  246. if ((psa^.Flags and ARR_DISPATCH) <> 0) or
  247. ((psa^.Flags and ARR_UNKNOWN) <> 0) then
  248. Result:=varInterface
  249. else if (psa^.Flags AND ARR_OLESTR) <> 0 then
  250. Result:=varWideString
  251. else
  252. Result:=vatNormal;
  253. end;
  254. Function SafeArrayClearDataSpace(psa: PVarArray; WipeBytes: Boolean {= True}): HRESULT;
  255. var
  256. I : Integer;
  257. vat: TVariantArrayType;
  258. begin
  259. try
  260. vat:=VariantArrayType(psa);
  261. case vat of
  262. vatNormal : FillChar(psa^.Data^,
  263. SafeArrayElementTotal(psa)*psa^.ElementSize,
  264. 0);
  265. varInterface : NoInterfaces;
  266. varWideString : NoWidestrings;
  267. end;
  268. Result:=VAR_OK;
  269. except
  270. On E : Exception do
  271. Result:=ExceptionToVariantError (E);
  272. end;
  273. end;
  274. Function SafeArrayCopyDataSpace(psa, psaOut: PVarArray): HRESULT;
  275. var
  276. I : Integer;
  277. vVargSrc, vTarget: Pointer;
  278. vat: TVariantArrayType;
  279. begin
  280. try
  281. vat:=VariantArrayType(psa);
  282. case vat of
  283. vatNormal: Move(psa^.Data^,
  284. psaOut^.Data^,
  285. SafeArrayElementTotal(psa)*psa^.ElementSize);
  286. varInterface : NoInterfaces; // Copy element per element...
  287. varWideString: NoWideStrings; // here also...
  288. end;
  289. Result:=VAR_OK;
  290. except
  291. On E : Exception do
  292. Result:=ExceptionToVariantError(E);
  293. end;
  294. end;
  295. Type
  296. TVartypes = varEmpty..varByte;
  297. Const
  298. Supportedpsas : set of TVarTypes =
  299. [varSmallint,varInteger,varSingle,varDouble,varCurrency,varDate,varOleStr,
  300. varDispatch,varError,varBoolean,varVariant,varUnknown,varByte];
  301. psaElementSizes : Array [varEmpty..varByte] of Byte =
  302. (0,0,2,4,4,8,8,8,4,4,4,2,16,4,0,0,0,1);
  303. psaElementFlags : Array [varEmpty..varByte] of Longint =
  304. (ARR_NONE,ARR_NONE,ARR_NONE,ARR_NONE,ARR_NONE,ARR_NONE,ARR_NONE,ARR_NONE,
  305. ARR_OLESTR,ARR_DISPATCH,ARR_NONE,ARR_NONE,ARR_NONE,ARR_UNKNOWN,
  306. ARR_NONE,ARR_NONE,ARR_NONE,ARR_NONE);
  307. Function SafeArrayCreate(VarType, Dim: Integer; const Bounds: TVarArrayBoundArray): PVarArray;stdcall;
  308. var
  309. res : HRESULT;
  310. I : Longint;
  311. begin
  312. Result:=nil;
  313. if Not (VarType in Supportedpsas) Then
  314. exit;
  315. Res:=SafeArrayAllocDescriptor(Dim, Result);
  316. if Res<>VAR_OK then
  317. exit;
  318. With Result^ do
  319. begin
  320. DimCount:=Dim;
  321. Flags:=psaElementFlags[VarType];
  322. ElementSize:=psaElementSizes[VarType];
  323. for i:=0 to Dim-1 do
  324. begin
  325. Bounds[i].LowBound:=Bounds[Dim-I-1].LowBound;
  326. Bounds[I].ElementCount:=Bounds[Dim-I-1].ElementCount;
  327. end;
  328. end;
  329. res:=SafeArrayAllocData(Result);
  330. if res<>VAR_OK then
  331. begin
  332. SafeArrayDestroyDescriptor(Result);
  333. Result:=nil;
  334. end;
  335. end;
  336. Function SafeArrayAllocDescriptor(DimCount: Integer; var psa: PVarArray): HRESULT;stdcall;
  337. begin
  338. try
  339. psa:=GetMem(SizeOf(TVarArray) + SizeOf(TVarArrayBound) * (DimCount - 1));
  340. Result:=VAR_OK;
  341. except
  342. On E : Exception do
  343. Result:=ExceptionToVariantError(E);
  344. end;
  345. end;
  346. Function SafeArrayAllocData(psa: PVarArray): HRESULT;stdcall;
  347. begin
  348. try
  349. With psa^ do
  350. Data:=GetMem(SafeArrayElementTotal(psa)*ElementSize);
  351. Result:=VAR_OK;
  352. except
  353. On E : Exception do
  354. Result:=ExceptionToVariantError(E);
  355. end;
  356. end;
  357. Function SafeArrayDestroy(psa: PVarArray): HRESULT;stdcall;
  358. begin
  359. Result:=CheckVarArray(psa);
  360. if Result<> VAR_OK then
  361. exit;
  362. Result:=CheckArrayUnlocked(psa);
  363. if Result<> VAR_OK then
  364. exit;
  365. Result:=SafeArrayDestroyData(psa);
  366. if Result<>VAR_OK then
  367. exit;
  368. Result:=SafeArrayDestroyDescriptor(psa);
  369. end;
  370. Function SafeArrayDestroyDescriptor(psa: PVarArray): HRESULT;stdcall;
  371. begin
  372. Result:=CheckVarArray(psa);
  373. if Result<>VAR_OK then
  374. exit;
  375. Result:=CheckArrayUnlocked(psa);
  376. if Result<> VAR_OK then
  377. exit;
  378. try
  379. FreeMem(psa);
  380. except
  381. On E : Exception do
  382. Result:=ExceptionToVariantError(E);
  383. end;
  384. end;
  385. Function SafeArrayDestroyData(psa: PVarArray): HRESULT;stdcall;
  386. begin
  387. Result:=CheckVarArray(psa);
  388. if Result<>VAR_OK then
  389. exit;
  390. Result:=CheckArrayUnlocked(psa);
  391. if Result<> VAR_OK then
  392. exit;
  393. try
  394. Result:=SafeArrayClearDataSpace(psa, False);
  395. if (Result=VAR_OK) and ((psa^.Flags and ARR_FIXEDSIZE)=0) then
  396. begin
  397. FreeMem(psa^.Data);
  398. psa^.Data:=nil;
  399. end;
  400. except
  401. On E : Exception do
  402. Result:=ExceptionToVariantError(E);
  403. end;
  404. end;
  405. Function SafeArrayRedim(psa: PVarArray; const NewBound: TVarArrayBound): HRESULT;stdcall;
  406. var
  407. vat: TVariantArrayType;
  408. i, D,j,count : Integer;
  409. P : Pointer;
  410. begin
  411. Result:=CheckVarArray(psa);
  412. if Result <> VAR_OK then
  413. exit;
  414. if (psa^.Flags and ARR_FIXEDSIZE) <> 0 then
  415. Exit(VAR_INVALIDARG);
  416. Result:=SafeArrayLock(psa);
  417. if Result<>VAR_OK then
  418. exit;
  419. try
  420. D:=NewBound.ElementCount - psa^.Bounds[0].ElementCount;
  421. for i:=1 to psa^.DimCount - 1 do
  422. D:=D*psa^.Bounds[i].ElementCount;
  423. if D<>0 then
  424. begin
  425. Count:=SafeArrayElementTotal(psa);
  426. if D<0 then
  427. begin
  428. vat:=VariantArrayType(psa);
  429. for j:=Count-1 downto Count+D do
  430. begin
  431. P:=SafeArrayCalculateElementAddress(psa,j);
  432. if vat = varInterface then
  433. NoInterfaces // Set to nil
  434. else
  435. NoWideStrings; // Set to empty...
  436. end;
  437. end;
  438. ReAllocMem(psa^.Data,Count+D);
  439. end;
  440. psa^.Bounds[0].ElementCount:=NewBound.ElementCount;
  441. psa^.Bounds[0].LowBound:=NewBound.LowBound;
  442. except
  443. On E : Exception do
  444. Result:=ExceptionToVariantError(E);
  445. end;
  446. SetUnlockResult(psa,Result);
  447. end;
  448. Function SafeArrayCopy(psa: PVarArray; var psaOut: PVarArray): HRESULT;stdcall;
  449. var
  450. i : Integer;
  451. begin
  452. Result:=CheckVarArray(psa);
  453. if Result<>VAR_OK then
  454. exit;
  455. Result:=SafeArrayLock(psa);
  456. if Result<>VAR_OK then
  457. exit;
  458. try
  459. Result:=SafeArrayAllocDescriptor(psa^.DimCount,psaOut);
  460. if Result<>VAR_OK then
  461. Exit;
  462. try
  463. With psaOut^ do
  464. begin
  465. Flags:=psa^.Flags;
  466. ElementSize:=psa^.ElementSize;
  467. DimCount:=psa^.DimCount;
  468. for i:=0 to DimCount-1 do
  469. begin
  470. Bounds[i].ElementCount:=psa^.Bounds[i].ElementCount;
  471. Bounds[i].LowBound:=psa^.Bounds[i].LowBound;
  472. end;
  473. end;
  474. Result:=SafeArrayAllocData(psaOut);
  475. if Result<>VAR_OK then
  476. exit;
  477. Result:=SafeArrayCopyDataSpace(psa, psaOut);
  478. finally
  479. if Result<>VAR_OK then
  480. begin
  481. SafeArrayDestroyDescriptor(psaOut);
  482. psaOut:=nil;
  483. end;
  484. end;
  485. except
  486. On E : Exception do
  487. Result:=ExceptionToVariantError(E)
  488. end;
  489. SetUnlockResult(psa,Result);
  490. end;
  491. Function SafeArrayCopyData(psa, psaOut: PVarArray): HRESULT;stdcall;
  492. var
  493. i : Integer;
  494. begin
  495. Result:=CheckVarArray(psa);
  496. if Result<>VAR_OK then
  497. exit;
  498. Result:=CheckVarArray(psaOut);
  499. if Result<>VAR_OK then
  500. exit;
  501. Result:=SafeArrayLock(psaOut);
  502. if Result<>VAR_OK then
  503. exit;
  504. try
  505. Result:=SafeArrayLock(psa);
  506. if Result<>VAR_OK then
  507. exit;
  508. try
  509. With psaOut^ do
  510. begin
  511. if (psa^.Flags<>Flags) or
  512. (psa^.ElementSize<>ElementSize) or
  513. (psa^.DimCount<>DimCount) then
  514. Exit(VAR_INVALIDARG);
  515. for i:=0 to psa^.DimCount - 1 do
  516. if (psa^.Bounds[i].LowBound<>Bounds[i].LowBound) or
  517. (psa^.Bounds[i].ElementCount<>Bounds[i].ElementCount) then
  518. exit(VAR_INVALIDARG);
  519. end;
  520. Result:=SafeArrayClearDataSpace(psaOut,True);
  521. if Result<> VAR_OK then
  522. exit;
  523. Result:=SafeArrayCopyDataSpace(psa, psaOut);
  524. finally
  525. SetUnlockResult(psa,Result);
  526. end;
  527. finally
  528. SetUnlockResult(psaOut,Result);
  529. end;
  530. end;
  531. Function SafeArrayGetLBound(psa: PVarArray; Dim: Integer; var LBound: Integer): HRESULT;stdcall;
  532. begin
  533. Result:=CheckVarArray(psa);
  534. if Result<>VAR_OK then
  535. exit;
  536. if (Dim>0) and (Dim<=psa^.DimCount) then
  537. LBound:=psa^.Bounds[Dim-1].LowBound
  538. else
  539. Result:=VAR_BADINDEX;
  540. end;
  541. Function SafeArrayGetUBound(psa: PVarArray; Dim: Integer; var UBound: Integer): HRESULT;stdcall;
  542. begin
  543. Result:=CheckVarArray(psa);
  544. if Result<>VAR_OK then
  545. exit;
  546. if (Dim>0) and (Dim<=psa^.DimCount) then
  547. UBound:=psa^.Bounds[Dim-1].LowBound +
  548. psa^.Bounds[Dim-1].ElementCount-1
  549. else
  550. Result:=VAR_BADINDEX
  551. end;
  552. Function SafeArrayGetDim(psa: PVarArray): Integer;stdcall;
  553. begin
  554. if CheckVarArray(psa)<>VAR_OK then
  555. Result:=0
  556. else
  557. Result:=psa^.DimCount;
  558. end;
  559. Function SafeArrayAccessData(psa: PVarArray; var ppvData: Pointer): HRESULT;stdcall;
  560. begin
  561. Result:=SafeArrayLock(psa);
  562. if Result<>VAR_OK then
  563. ppvData:=nil
  564. else
  565. ppvData:=psa^.Data;
  566. end;
  567. Function SafeArrayUnaccessData(psa: PVarArray): HRESULT;stdcall;
  568. begin
  569. Result:=SafeArrayUnlock(psa);
  570. end;
  571. Function SafeArrayLock(psa: PVarArray): HRESULT;stdcall;
  572. begin
  573. Result:=CheckVarArray(psa);
  574. if Result<>VAR_OK then
  575. exit;
  576. Inc(psa^.LockCount);
  577. end;
  578. Function SafeArrayUnlock(psa: PVarArray): HRESULT;stdcall;
  579. begin
  580. Result:=CheckVarArray(psa);
  581. if (Result<>VAR_OK) then
  582. exit;
  583. If (psa^.LockCount>0) then
  584. Dec(psa^.LockCount);
  585. end;
  586. Function SafeArrayGetElement(psa: PVarArray; Indices: PVarArrayCoorArray;
  587. Data: Pointer): HRESULT;stdcall;
  588. var
  589. P: Pointer;
  590. begin
  591. Result:=CheckVarArrayAndCalculateAddress(psa, Indices, P, True);
  592. if Result<>VAR_OK then
  593. exit;
  594. try
  595. case VariantArrayType(psa) of
  596. vatNormal:
  597. Move(P^, Data^, psa^.ElementSize);
  598. varInterface:
  599. NoInterfaces; // Just assign...
  600. varWideString:
  601. NoWideStrings; // Just assign...
  602. end;
  603. except
  604. On E : Exception do
  605. Result:=ExceptionToVariantError(E);
  606. end;
  607. SetUnlockResult(psa,Result);
  608. end;
  609. Function SafeArrayPutElement(psa: PVarArray; Indices: PVarArrayCoorArray;
  610. const Data: Pointer): HRESULT;stdcall;
  611. var
  612. P: Pointer;
  613. begin
  614. Result:=CheckVarArrayAndCalculateAddress(psa,Indices,P,True);
  615. if Result<>VAR_OK then
  616. exit;
  617. try
  618. case VariantArrayType(psa) of
  619. vatNormal: Move(Data^,P^,psa^.ElementSize);
  620. varInterface: NoInterfaces;
  621. varWideString: NoWideStrings;
  622. end;
  623. except
  624. On E : Exception do
  625. Result:=ExceptionToVariantError(E);
  626. end;
  627. SetUnlockResult(psa,Result);
  628. end;
  629. Function SafeArrayPtrOfIndex(psa: PVarArray; Indices: PVarArrayCoorArray;
  630. var Address: Pointer): HRESULT;stdcall;
  631. begin
  632. Result:=CheckVarArrayAndCalculateAddress(psa,Indices,Address,False);
  633. end;
  634. Function SafeArrayGetElemSize(psa: PVarArray): LongWord;stdcall;
  635. begin
  636. if CheckVarArray(psa)<>VAR_OK then
  637. Result:=0
  638. else
  639. Result:=psa^.ElementSize;
  640. end;
  641. {$endif HASVARIANT}
  642. {
  643. $Log$
  644. Revision 1.10 2002-11-22 16:30:05 peter
  645. * Widestring->PWidechar requires a typecast
  646. Revision 1.9 2002/10/11 12:21:55 florian
  647. * fixes for new widestring handling
  648. Revision 1.8 2002/09/07 16:01:23 peter
  649. * old logs removed and tabs fixed
  650. }