varutils.inc 18 KB

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