1 /*******************************************************************************
2 * Copyright (c) 2000, 2017 IBM Corporation and others.
4 * This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License 2.0
6 * which accompanies this distribution, and is available at
7 * https://www.eclipse.org/legal/epl-2.0/
9 * SPDX-License-Identifier: EPL-2.0
12 * IBM Corporation - initial API and implementation
13 *******************************************************************************/
14 package org.eclipse.swt.dnd;
16 import org.eclipse.swt.internal.*;
17 import org.eclipse.swt.internal.ole.win32.*;
18 import org.eclipse.swt.internal.win32.*;
20 final class OleEnumFORMATETC {
22 private COMObject iEnumFORMATETC;
27 private FORMATETC[] formats;
31 createCOMInterfaces();
38 private void createCOMInterfaces() {
39 iEnumFORMATETC = new COMObject(new int[] {2, 0, 0, 3, 1, 0, 1}){
41 public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
43 public long method1(long[] args) {return AddRef();}
45 public long method2(long[] args) {return Release();}
47 public long method3(long[] args) {return Next((int)args[0], args[1], args[2]);}
49 public long method4(long[] args) {return Skip((int)args[0]);}
51 public long method5(long[] args) {return Reset();}
52 // method6 Clone - not implemented
55 private void disposeCOMInterfaces() {
56 if (iEnumFORMATETC != null)
57 iEnumFORMATETC.dispose();
58 iEnumFORMATETC = null;
61 return iEnumFORMATETC.getAddress();
63 private FORMATETC[] getNextItems(int numItems){
65 if (formats == null || numItems < 1) return null;
67 int endIndex = index + numItems - 1;
68 if (endIndex > (formats.length - 1)) endIndex = formats.length - 1;
69 if (index > endIndex) return null;
71 FORMATETC[] items = new FORMATETC[endIndex - index + 1];
72 for (int i = 0; i < items.length; i++){
73 items[i] = formats[index];
79 private int Next(int celt, long rgelt, long pceltFetched) {
80 /* Retrieves the next celt items in the enumeration sequence.
81 If there are fewer than the requested number of elements left in the sequence,
82 it retrieves the remaining elements.
83 The number of elements actually retrieved is returned through pceltFetched
84 (unless the caller passed in NULL for that parameter).
87 if (rgelt == 0) return COM.E_INVALIDARG;
88 if (pceltFetched == 0 && celt != 1) return COM.E_INVALIDARG;
90 FORMATETC[] nextItems = getNextItems(celt);
91 if (nextItems != null) {
92 for (int i = 0; i < nextItems.length; i++) {
93 COM.MoveMemory(rgelt + i*FORMATETC.sizeof, nextItems[i], FORMATETC.sizeof);
96 if (pceltFetched != 0)
97 OS.MoveMemory(pceltFetched, new int[] {nextItems.length}, 4);
99 if (nextItems.length == celt) return COM.S_OK;
102 if (pceltFetched != 0)
103 OS.MoveMemory(pceltFetched, new int[] {0}, 4);
104 COM.MoveMemory(rgelt, new FORMATETC(), FORMATETC.sizeof);
109 private int QueryInterface(long riid, long ppvObject) {
111 if (riid == 0 || ppvObject == 0) return COM.E_NOINTERFACE;
113 GUID guid = new GUID();
114 COM.MoveMemory(guid, riid, GUID.sizeof);
116 if (COM.IsEqualGUID(guid, COM.IIDIUnknown) || COM.IsEqualGUID(guid, COM.IIDIEnumFORMATETC)) {
117 OS.MoveMemory(ppvObject, new long[] {iEnumFORMATETC.getAddress()}, C.PTR_SIZEOF);
121 OS.MoveMemory(ppvObject, new long[] {0}, C.PTR_SIZEOF);
122 return COM.E_NOINTERFACE;
128 disposeCOMInterfaces();
129 if (COM.FreeUnusedLibraries) {
130 COM.CoFreeUnusedLibraries();
136 private int Reset() {
137 //Resets the enumeration sequence to the beginning.
141 void setFormats(FORMATETC[] newFormats) {
142 formats = newFormats;
145 private int Skip(int celt) {
146 //Skips over the next specified number of elements in the enumeration sequence.
147 if (celt < 1 ) return COM.E_INVALIDARG;
150 if (index > (formats.length - 1)){
151 index = formats.length - 1;