| /* |
| * Word splitter Implementation |
| * |
| * Copyright 2006 Mike McCormack |
| * |
| * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
| */ |
| |
| #define COBJMACROS |
| |
| #include "config.h" |
| |
| #include <stdarg.h> |
| |
| #include "windef.h" |
| #include "winbase.h" |
| #include "winuser.h" |
| #include "ole2.h" |
| #include "indexsrv.h" |
| #include "wine/unicode.h" |
| #include "wine/debug.h" |
| |
| WINE_DEFAULT_DEBUG_CHANNEL(infosoft); |
| |
| typedef struct tag_wordbreaker_impl |
| { |
| const IWordBreakerVtbl *lpVtbl; |
| LONG ref; |
| } wordbreaker_impl; |
| |
| static HRESULT WINAPI wb_QueryInterface( IWordBreaker *iface, |
| REFIID riid, LPVOID *ppvObj) |
| { |
| wordbreaker_impl *This = (wordbreaker_impl *)iface; |
| |
| TRACE("(%p)->(%s)\n",This,debugstr_guid(riid)); |
| |
| *ppvObj = NULL; |
| |
| if (IsEqualIID(riid, &IID_IUnknown) || |
| IsEqualIID(riid, &IID_IWordBreaker)) |
| { |
| *ppvObj = This; |
| return S_OK; |
| } |
| |
| TRACE("-- E_NOINTERFACE\n"); |
| return E_NOINTERFACE; |
| } |
| |
| static ULONG WINAPI wb_AddRef( IWordBreaker *iface ) |
| { |
| wordbreaker_impl *This = (wordbreaker_impl *)iface; |
| return InterlockedIncrement(&This->ref); |
| } |
| |
| static ULONG WINAPI wb_Release(IWordBreaker *iface) |
| { |
| wordbreaker_impl *This = (wordbreaker_impl *)iface; |
| LONG refcount; |
| |
| refcount = InterlockedDecrement(&This->ref); |
| if (!refcount) |
| HeapFree(GetProcessHeap(), 0, This); |
| |
| return refcount; |
| } |
| |
| static HRESULT WINAPI wb_Init( IWordBreaker *iface, |
| BOOL fQuery, ULONG ulMaxTokenSize, BOOL *pfLicense ) |
| { |
| TRACE("%d %u\n", fQuery, ulMaxTokenSize); |
| *pfLicense = FALSE; |
| return S_OK; |
| } |
| |
| static HRESULT call_sink( IWordSink *pWordSink, TEXT_SOURCE *ts, UINT len ) |
| { |
| HRESULT r; |
| |
| if (!len) |
| return S_OK; |
| |
| TRACE("%d %s\n", len, debugstr_w(&ts->awcBuffer[ts->iCur])); |
| |
| r = IWordSink_PutWord( pWordSink, len, &ts->awcBuffer[ts->iCur], len, ts->iCur ); |
| ts->iCur += len; |
| |
| return r; |
| } |
| |
| static HRESULT WINAPI wb_BreakText( IWordBreaker *iface, |
| TEXT_SOURCE *ts, IWordSink *pWordSink, IPhraseSink *pPhraseSink) |
| { |
| UINT len, state = 0; |
| WCHAR ch; |
| |
| TRACE("%p %p %p\n", ts, pWordSink, pPhraseSink); |
| |
| if (pPhraseSink) |
| FIXME("IPhraseSink won't be called\n"); |
| |
| do |
| { |
| len = 0; |
| while ((ts->iCur + len) < ts->iEnd) |
| { |
| ch = ts->awcBuffer[ts->iCur + len]; |
| |
| switch (state) |
| { |
| case 0: /* skip spaces and punctuation */ |
| |
| if (!ch || ispunctW(ch) || isspaceW(ch)) |
| ts->iCur ++; |
| else |
| state = 1; |
| break; |
| |
| case 1: /* find the end of the word */ |
| |
| if (ch && !ispunctW(ch) && !isspaceW(ch)) |
| len++; |
| else |
| { |
| call_sink( pWordSink, ts, len ); |
| len = 0; |
| state = 0; |
| } |
| break; |
| |
| } |
| } |
| call_sink( pWordSink, ts, len ); |
| |
| } while (S_OK == ts->pfnFillTextBuffer( ts )); |
| |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI wb_ComposePhrase( IWordBreaker *iface, |
| const WCHAR *pwcNoun, ULONG cwcNoun, |
| const WCHAR *pwcModifier, ULONG cwcModifier, |
| ULONG ulAttachmentType, WCHAR *pwcPhrase, ULONG *pcwcPhrase) |
| { |
| FIXME("%p %u %p %u %u %p %p\n", pwcNoun, cwcNoun, |
| pwcModifier, cwcModifier, ulAttachmentType, pwcPhrase, pcwcPhrase); |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI wb_GetLicenseToUse( IWordBreaker *iface, const WCHAR **ppwcsLicense ) |
| { |
| FIXME("%p\n", ppwcsLicense); |
| *ppwcsLicense = NULL; |
| return S_OK; |
| } |
| |
| static const IWordBreakerVtbl wordbreaker_vtbl = |
| { |
| wb_QueryInterface, |
| wb_AddRef, |
| wb_Release, |
| wb_Init, |
| wb_BreakText, |
| wb_ComposePhrase, |
| wb_GetLicenseToUse, |
| }; |
| |
| HRESULT WINAPI wb_Constructor(IUnknown* pUnkOuter, REFIID riid, LPVOID *ppvObject) |
| { |
| wordbreaker_impl *This; |
| IWordBreaker *wb; |
| |
| TRACE("%p %s %p\n", pUnkOuter, debugstr_guid(riid), ppvObject); |
| |
| This = HeapAlloc(GetProcessHeap(), 0, sizeof *This); |
| if (!This) |
| return E_OUTOFMEMORY; |
| |
| This->ref = 1; |
| This->lpVtbl = &wordbreaker_vtbl; |
| |
| wb = (IWordBreaker*) This; |
| |
| return IWordBreaker_QueryInterface(wb, riid, ppvObject); |
| } |