diff --git a/array.go b/array.go index cd8d542..cf26e21 100644 --- a/array.go +++ b/array.go @@ -200,7 +200,7 @@ func NewArrayIterator(items []any, itemSignature string) *collections.IIterator inst.Mutex = sync.Mutex{} inst.refs = 0 inst.itemSignature = itemSignature - inst.index = -1 // not initialized + inst.index = 0 inst.AddRef() return &inst.IIterator // ugly but works @@ -252,6 +252,9 @@ func getCurrent(inst, out unsafe.Pointer) uintptr { return ole.E_FAIL } + if len(items) < 1 || it.index >= len(items) { + return ole.E_FAIL + } current := items[it.index] copyItemToPointer(current, out) @@ -299,7 +302,7 @@ func getMany(inst, itemsAmount, outItems, outItemsSize unsafe.Pointer) uintptr { // requested itemsAmount requestedItems := int(uintptr(itemsAmount)) - availableItems := len(items) - it.index - 1 + availableItems := len(items) - it.index returnItems := requestedItems if returnItems > availableItems { // not enough items available @@ -309,8 +312,13 @@ func getMany(inst, itemsAmount, outItems, outItemsSize unsafe.Pointer) uintptr { // copy items n := uintptr(0) for i := 0; i < returnItems; i++ { - it.index++ n += copyItemToPointer(items[it.index], unsafe.Pointer(uintptr(outItems)+n)) + it.index++ + } + + // Advance the index beyond the last retrieved item + if it.index >= len(items)-1 { + it.index = len(items) } // output size diff --git a/array_test.go b/array_test.go new file mode 100644 index 0000000..030f948 --- /dev/null +++ b/array_test.go @@ -0,0 +1,76 @@ +package winrt + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func Test_GetEmpty(t *testing.T) { + a := NewArrayIterable([]any{}, SignatureInt32) + it, err := a.First() + require.NoError(t, err) + + ok, err := it.GetHasCurrent() + require.NoError(t, err) + require.False(t, ok) +} + +func Test_GetCurrent(t *testing.T) { + a := NewArrayIterable([]any{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, SignatureInt32) + + it, err := a.First() + require.NoError(t, err) + + i := 1 + for { + hasMore, err := it.GetHasCurrent() + require.NoError(t, err) + if !hasMore { + break + } + + ptr, err := it.GetCurrent() + require.NoError(t, err) + require.Equal(t, i, int(uintptr(ptr))) + _, err = it.MoveNext() + require.NoError(t, err) + i++ + } + require.Equal(t, 11, i) +} + +func Test_GetMany(t *testing.T) { + a := NewArrayIterable([]any{101, 202, 303}, SignatureInt32) + + it, err := a.First() + require.NoError(t, err) + + r3, err := it.GetCurrent() + require.NoError(t, err) + require.True(t, int(uintptr(r3)) == 101) + + resp, n, err := it.GetMany(12) + require.NoError(t, err) + require.Equal(t, uint32(3), n) + + var i uint32 + var j int = 101 + for i = 0; i < n; i++ { + val := int(uintptr(resp[i])) + require.Equal(t, j, val) + j += 101 + } + + // no more items + hasMore, err := it.GetHasCurrent() + require.NoError(t, err) + require.False(t, hasMore) + + _, err = it.GetCurrent() + require.Error(t, err) + + ok, err := it.MoveNext() + require.NoError(t, err) + require.False(t, ok) +} diff --git a/windows/storage/provider/storage_test.go b/windows/storage/provider/storage_test.go new file mode 100644 index 0000000..6296e9c --- /dev/null +++ b/windows/storage/provider/storage_test.go @@ -0,0 +1,53 @@ +package provider + +import ( + "fmt" + "testing" + "unsafe" + + "github.com/go-ole/go-ole" + "github.com/saltosystems/winrt-go" + "github.com/stretchr/testify/require" +) + +func init() { + ole.CoInitialize(0) +} + +func Test_GetMany_StorageProperyItem(t *testing.T) { + prop1, err := NewStorageProviderItemProperty() + require.NoError(t, err) + prop1.SetId(1) + prop1.SetValue("Value1") + prop1.SetIconResource("shell32.dll,-44") + + prop2, err := NewStorageProviderItemProperty() + require.NoError(t, err) + prop2.SetId(2) + prop2.SetValue("Value2") + prop2.SetIconResource("shell32.dll,-44") + + a := winrt.NewArrayIterable([]any{prop1, prop2}, SignatureStorageProviderItemProperty) + + it, err := a.First() + require.NoError(t, err) + resp, n, err := it.GetMany(3) // only 2 is available + require.NoError(t, err) + require.Equal(t, uint32(2), n) + + // Extract and print the StorageProviderItemProperty objects + for i := uint32(0); i < n; i++ { + itemPtr := unsafe.Pointer(resp[i]) + item := (*StorageProviderItemProperty)(itemPtr) + // Access properties of the StorageProviderItemProperty + id, err := item.GetId() + require.NoError(t, err) + require.Equal(t, int32(i+1), id) + value, err := item.GetValue() + require.NoError(t, err) + require.Equal(t, fmt.Sprintf("Value%d", i+1), value) + iconResource, err := item.GetIconResource() + require.NoError(t, err) + require.Equal(t, "shell32.dll,-44", iconResource) + } +}