/*
 * SHLWAPI Compact List functions
 *
 * Copyright 2002 Jon Griffiths
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#include <string.h>

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "objbase.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(shell);

/* Compact list element (ordinals 17-22) */
typedef struct tagSHLWAPI_CLIST
{
  ULONG ulSize;        /* Size of this list element and its data */
  ULONG ulId;          /* If -1, The real element follows        */
  /* Item data (or a contained SHLWAPI_CLIST) follows...         */
} SHLWAPI_CLIST, *LPSHLWAPI_CLIST;

typedef const SHLWAPI_CLIST* LPCSHLWAPI_CLIST;

/* ulId for contained SHLWAPI_CLIST items */
static const ULONG CLIST_ID_CONTAINER = -1u;

HRESULT WINAPI SHLWAPI_20(LPSHLWAPI_CLIST*,LPCSHLWAPI_CLIST);

/*************************************************************************
 * NextItem
 *
 * Internal helper: move a clist pointer to the next item.
 */
inline static LPSHLWAPI_CLIST NextItem(LPCSHLWAPI_CLIST lpList)
{
  const char* address = (char*)lpList;
  address += lpList->ulSize;
  return (LPSHLWAPI_CLIST)address;
}

/*************************************************************************
 *      @	[SHLWAPI.17]
 *
 * Write a compact list to an IStream object.
 *
 * PARAMS
 *  lpStream  [I] IStream object to write the list to
 *  lpList    [I] List of items to write
 *
 * RETURNS
 *  Success: S_OK. The object is written to the stream.
 *  Failure: An HRESULT error code
 *
 * NOTES
 *  Ordinals 17,18,19,20,21 and 22 are related and together provide a compact
 *  list structure which may be stored and retrieved from an IStream object.
 *
 *  The exposed API consists of:
 *
 *   SHLWAPI_17() Write a compact list to a stream,
 *
 *   SHLWAPI_18() Read and create a list from a stream,
 *
 *   SHLWAPI_19() Free a list,
 *
 *   SHLWAPI_20() Insert a new item into a list,
 *
 *   SHLWAPI_21() Remove an item from a list,
 *
 *   SHLWAPI_22() Find an item in a list.
 *
 *  The compact list is stored packed into a memory array. Each element has a
 *  size and an associated ID. Elements must be less than 64k if the list is
 *  to be subsequently read from a stream.
 *
 *  Elements are aligned on DWORD boundaries. If an elements data size is not
 *  a DWORD size multiple, the element is wrapped by inserting a surrounding
 *  element with an Id of -1, and size sufficient to pad to a DWORD boundary.
 *
 *  These functions are slow for large objects and long lists.
 */
HRESULT WINAPI SHLWAPI_17(IStream* lpStream, LPSHLWAPI_CLIST lpList)
{
  ULONG ulSize;
  HRESULT hRet = E_FAIL;

  TRACE("(%p,%p)\n", lpStream, lpList);

  if(lpList)
  {
    while (lpList->ulSize)
    {
      LPSHLWAPI_CLIST lpItem = lpList;

      if(lpList->ulId == CLIST_ID_CONTAINER)
        lpItem++;

      hRet = IStream_Write(lpStream,lpItem,lpItem->ulSize,&ulSize);
      if (FAILED(hRet))
        return hRet;

      if(lpItem->ulSize != ulSize)
        return STG_E_MEDIUMFULL;

      lpList = NextItem(lpList);
    }
  }

  if(SUCCEEDED(hRet))
  {
    ULONG ulDummy;
    ulSize = 0;

    /* Write a terminating list entry with zero size */
    hRet = IStream_Write(lpStream, &ulSize,sizeof(ulSize),&ulDummy);
  }

  return hRet;
}

/*************************************************************************
 *      @	[SHLWAPI.18]
 *
 * Read and create a compact list from an IStream object.
 *
 * PARAMS
 *  lpStream  [I] Stream to read the list from
 *  lppList   [0] Pointer to recieve the new List
 *
 * RETURNS
 *  Success: S_OK
 *  Failure: An HRESULT error code
 *
 * NOTES
 *  When read from a file, list objects are limited in size to 64k.
 *  See SHLWAPI_17.
 */
HRESULT WINAPI SHLWAPI_18(IStream* lpStream, LPSHLWAPI_CLIST* lppList)
{
  SHLWAPI_CLIST bBuff[128]; /* Temporary storage for new list item */
  ULONG ulBuffSize = sizeof(bBuff);
  LPSHLWAPI_CLIST pItem = bBuff;
  ULONG ulRead, ulSize;
  HRESULT hRet = S_OK;

  TRACE("(%p,%p)\n", lpStream, lppList);

  if(*lppList)
  {
    /* Free any existing list */
    LocalFree((HLOCAL)*lppList);
    *lppList = NULL;
  }

  do
  {
    /* Read the size of the next item */
    hRet = IStream_Read(lpStream, &ulSize,sizeof(ulSize),&ulRead);

    if(FAILED(hRet) || ulRead != sizeof(ulSize) || !ulSize)
      break; /* Read failed or read zero size (the end of the list) */

    if(ulSize > 0xFFFF)
    {
      LARGE_INTEGER liZero;
      ULARGE_INTEGER ulPos;

      liZero.QuadPart = 0;

      /* Back the stream up; this object is too big for the list */
      if(SUCCEEDED(IStream_Seek(lpStream, liZero, STREAM_SEEK_CUR, &ulPos)))
      {
        liZero.QuadPart = ulPos.QuadPart - sizeof(ULONG);
        IStream_Seek(lpStream, liZero, STREAM_SEEK_SET, NULL);
      }
      break;
    }
    else if (ulSize >= sizeof(SHLWAPI_CLIST))
    {
      /* Add this new item to the list */
      if(ulSize > ulBuffSize)
      {
        /* We need more buffer space, allocate it */
        LPSHLWAPI_CLIST lpTemp;

        if (pItem == bBuff)
          lpTemp = (LPSHLWAPI_CLIST)LocalAlloc(LMEM_ZEROINIT, ulSize);
        else
          lpTemp = (LPSHLWAPI_CLIST)LocalReAlloc((HLOCAL)pItem, ulSize,
                                                 LMEM_ZEROINIT|LMEM_MOVEABLE);

        if(!lpTemp)
        {
          hRet = E_OUTOFMEMORY;
          break;
        }
        ulBuffSize = ulSize;
        pItem = lpTemp;
      }

      pItem->ulSize = ulSize;
      ulSize -= sizeof(pItem->ulSize); /* already read this member */

      /* Read the item Id and data */
      hRet = IStream_Read(lpStream, &pItem->ulId, ulSize, &ulRead);

      if(FAILED(hRet) || ulRead != ulSize)
        break;

      SHLWAPI_20(lppList, pItem); /* Insert Item */
    }
  } while(1);

  /* If we allocated space, free it */
  if(pItem != bBuff)
    LocalFree((HLOCAL)pItem);

  return hRet;
}

/*************************************************************************
 *      @	[SHLWAPI.19]
 *
 * Free a compact list.
 *
 * PARAMS
 *  lpList [I] List to free
 *
 * RETURNS
 *  Nothing.
 *
 * NOTES
 *  See SHLWAPI_17.
 */
VOID WINAPI SHLWAPI_19(LPSHLWAPI_CLIST lpList)
{
  TRACE("(%p)\n", lpList);

  if (lpList)
    LocalFree((HLOCAL)lpList);
}

/*************************************************************************
 *      @	[SHLWAPI.20]
 *
 * Insert a new item into a compact list.
 *
 * PARAMS
 *  lppList   [0] Pointer to the List
 *  lpNewItem [I] The new item to add to the list
 *
 * RETURNS
 *  Success: S_OK. The item is added to the list.
 *  Failure: An HRESULT error code.
 *
 * NOTES
 *  If the size of the element to be inserted is less than the size of a
 *  SHLWAPI_CLIST node, or the Id for the item is CLIST_ID_CONTAINER,
 *  the call returns S_OK but does not actually add the element.
 *  See SHLWAPI_17.
 */
HRESULT WINAPI SHLWAPI_20(LPSHLWAPI_CLIST* lppList, LPCSHLWAPI_CLIST lpNewItem)
{
  LPSHLWAPI_CLIST lpInsertAt = NULL;
  ULONG ulSize;

  TRACE("(%p,%p)\n", lppList, lpNewItem);

  if(!lppList || !lpNewItem )
    return E_INVALIDARG;

  if (lpNewItem->ulSize < sizeof(SHLWAPI_CLIST) ||
      lpNewItem->ulId == CLIST_ID_CONTAINER)
    return S_OK;

  ulSize = lpNewItem->ulSize;

  if(ulSize & 0x3)
  {
    /* Tune size to a ULONG boundary, add space for container element */
    ulSize = ((ulSize + 0x3) & 0xFFFFFFFC) + sizeof(SHLWAPI_CLIST);
    TRACE("Creating container item, new size = %ld\n", ulSize);
  }

  if(!*lppList)
  {
    /* An empty list. Allocate space for terminal ulSize also */
    *lppList = (LPSHLWAPI_CLIST)LocalAlloc(LMEM_ZEROINIT,
                                           ulSize + sizeof(ULONG));
    lpInsertAt = *lppList;
  }
  else
  {
    /* Append to the end of the list */
    ULONG ulTotalSize = 0;
    LPSHLWAPI_CLIST lpIter = *lppList;

    /* Iterate to the end of the list, calculating the total size */
    while (lpIter->ulSize)
    {
      ulTotalSize += lpIter->ulSize;
      lpIter = NextItem(lpIter);
    }

    /* Increase the size of the list */
    lpIter = (LPSHLWAPI_CLIST)LocalReAlloc((HLOCAL)*lppList,
                                          ulTotalSize + ulSize+sizeof(ULONG),
                                          LMEM_ZEROINIT | LMEM_MOVEABLE);
    if(lpIter)
    {
      *lppList = lpIter;
      lpInsertAt = (LPSHLWAPI_CLIST)((char*)lpIter + ulTotalSize); /* At end */
    }
  }

  if(lpInsertAt)
  {
    /* Copy in the new item */
    LPSHLWAPI_CLIST lpDest = lpInsertAt;

    if(ulSize != lpNewItem->ulSize)
    {
      lpInsertAt->ulSize = ulSize;
      lpInsertAt->ulId = CLIST_ID_CONTAINER;
      lpDest++;
    }
    memcpy(lpDest, lpNewItem, lpNewItem->ulSize);

    /* Terminate the list */
    lpInsertAt = NextItem(lpInsertAt);
    lpInsertAt->ulSize = 0;

    return lpNewItem->ulSize;
  }
  return S_OK;
}

/*************************************************************************
 *      @	[SHLWAPI.21]
 *
 * Remove an item from a compact list.
 *
 * PARAMS
 *  lppList [O] List to remove the item from
 *  ulId    [I] Id of item to remove
 *
 * RETURNS
 *  Success: TRUE.
 *  Failure: FALSE, If any parameters are invalid, or the item was not found.
 *
 * NOTES
 *  See SHLWAPI_17.
 */
BOOL WINAPI SHLWAPI_21(LPSHLWAPI_CLIST* lppList, ULONG ulId)
{
  LPSHLWAPI_CLIST lpList = 0;
  LPSHLWAPI_CLIST lpItem = NULL;
  LPSHLWAPI_CLIST lpNext;
  ULONG ulNewSize;

  TRACE("(%p,%ld)\n", lppList, ulId);

  if(lppList && (lpList = *lppList))
  {
    /* Search for item in list */
    while (lpList->ulSize)
    {
      if(lpList->ulId == ulId ||
        (lpList->ulId == CLIST_ID_CONTAINER && lpList[1].ulId == ulId))
      {
        lpItem = lpList; /* Found */
        break;
      }
      lpList = NextItem(lpList);
    }
  }

  if(!lpItem)
    return FALSE;

  lpList = lpNext = NextItem(lpItem);

  /* Locate the end of the list */
  while (lpList->ulSize)
    lpList = NextItem(lpList);

  /* Resize the list */
  ulNewSize = LocalSize((HLOCAL)*lppList) - lpItem->ulSize;

  /* Copy following elements over lpItem */
  memmove(lpItem, lpNext, (char *)lpList - (char *)lpNext + sizeof(ULONG));

  if(ulNewSize <= sizeof(ULONG))
  {
    LocalFree((HLOCAL)*lppList);
    *lppList = NULL; /* Removed the last element */
  }
  else
  {
    lpList = (LPSHLWAPI_CLIST)LocalReAlloc((HLOCAL)*lppList, ulNewSize,
                                           LMEM_ZEROINIT|LMEM_MOVEABLE);
    if(lpList)
      *lppList = lpList;
  }
  return TRUE;
}

/*************************************************************************
 *      @	[SHLWAPI.22]
 *
 * Find an item in a compact list.
 *
 * PARAMS
 *  lpList [I] List to search
 *  ulId   [I] Id of item to find
 *
 * RETURNS
 *  Success: A pointer to the list item found
 *  Failure: NULL
 *
 * NOTES
 *  See SHLWAPI_17.
 */
LPSHLWAPI_CLIST WINAPI SHLWAPI_22(LPSHLWAPI_CLIST lpList, ULONG ulId)
{
  TRACE("(%p,%ld)\n", lpList, ulId);

  if(lpList)
  {
    while(lpList->ulSize)
    {
      if(lpList->ulId == ulId)
        return lpList; /* Matched */
      else if(lpList->ulId == CLIST_ID_CONTAINER && lpList[1].ulId == ulId)
        return lpList + 1; /* Contained item matches */

      lpList = NextItem(lpList);
    }
  }
  return NULL;
}
