I would like to write some helper function to convert some pointer
pointing to a whchar_t*(windows unicode) to a standard utf8 string.
Here is the code I currently have :
void*
OS_GDAbItem_GetProperty(GDAbItem* gpContact, EAbItemProp eAbPropId)
{
ErrorCode err;
void* pRet = NULL;
CEPROPVAL *lpProp;
GDPropVal* gynPropVal = NULL;
err = GDAbItem_GetPropertyEx(gpContact, eAbPropId, &gynPropVal);
if (err == 0)
{
lpProp = (CEPROPVAL *) gynPropVal->pOsPropVal;
if (lpProp->wFlags != CEDB_PROPNOTFOUND)
{
switch( gynPropVal->ulPropType )
{
case CEVT_LPWSTR:
{
pRet = lpProp->val.lpwstr ;
#ifndef _UNICODE
// HERE I SHOULD convert val.lpwstr to a // utf8 string and
then deallocate // original string
#endif
break;
}
case CEVT_FILETIME:
{
pRet = &(lpProp->val.filetime)
;break;
}
}
}
}
return pRet
}
I would like to avoid to put #ifndef everywhere in my code, that's why I
wanted to make a simple class that would do the ugly job.
Actually the pointer I am interested in is a void* ie it can point to
anything BUT in the case I am assigning from a windows unicode string
(const wchar_t*) I want to do some specific action(convert into utf8).
So I am starting with this :
template <typename T>
class IConvPtr
{
public:
IConvPtr& IConvPtr::operator=(T* aptr)
{
m_ptr = aptr;
}
inline void* getPtr() { return m_ptr; }
private:
void* m_ptr;
};
But not sure this is a right way of doing it. So to sum up as long as
assigned pointer is not a const wchar_t* I just copy pointer otherwise I
do some action.
Hi! :-)
What's all this stuff about gynecologists?
I think it's off-topic for this group.
> I would like to avoid to put #ifndef everywhere in my code, that's why I
> wanted to make a simple class that would do the ugly job.
> Actually the pointer I am interested in is a void* ie it can point to
> anything BUT in the case I am assigning from a windows unicode string
> (const wchar_t*) I want to do some specific action(convert into utf8).
That also seems pretty irrelevant to your question.
> So I am starting with this :
>
> template <typename T>
> class IConvPtr
> {
> public:
> IConvPtr& IConvPtr::operator=(T* aptr)
> {
> m_ptr = aptr;
> }
> inline void* getPtr() { return m_ptr; }
> private:
> void* m_ptr;
> };
>
>
> But not sure this is a right way of doing it.
It isn't.
There's no single right way, but the above is definitely a Wrong Way(TM).
Don't have a void* pointer, don't use a template, don't use setters and getters,
and having said that, there's *nothing* relevant to your question in that code.
> So to sum up as long as
> assigned pointer is not a const wchar_t* I just copy pointer otherwise I
> do some action.
You should post this question to a Windows-specific group, because the easiest
way to do ->UTF8 conversion in Windows is to use (I nearly wrote sue, 'scuse me)
the Windows API instead of implementing it yourself. Implementing the conversion
yourself isn't hard though. But it's tedious, and the API may be more efficient.
The FAQ has some great suggestions for Windows-specific groups.
Check out the FAQ, it's almost always a good idea! :-)
Cheers & hth.,
- Alf
--
Due to hosting requirements I need visits to <url: http://alfps.izfree.com/>.
No ads, and there is some C++ stuff! :-) Just going there is good. Linking
to it is even better! Thanks in advance!
> What's all this stuff about gynecologists?
>
> I think it's off-topic for this group.
It's just for you to understand the context
I am really pissed off by that kind of answers, my question is not
windows specific. I DO KNOW ho to convert from ansi to unicode this is
not the problem.
I could ask my question by rewriting terms differently without
mentionning windows type or even windows.
This is a C++ question, on windows forums they don't know how to use
advanced C++ they will answer me to use WideCharToMultiByte function.
I DONT give a fu....
So here is my question asked differently :
in C++ (I insist) is it possible to write a kind of smart pointer that
when assigned from any type just copy the pointer EXCEPT when it's a
given type (for instance chat*).
something that would allow me to write :
IConvPtr iconvptr;
...
switch(ulPropType)
{
case TYPE_INT: { iconvPtr = &(lpProp->val.iValue); break; }
case TYPE_FLOAT: { iconvPtr = &(lpProp->val.fValue); break; }
case TYPE_STRING: { iconvPtr = &(lpProp->val.szValue); break; }
...
}
iconvPtr.getPtr()
so now don't tell me it's windows specific, ulProptype is a unsigned
long that tell me the type of the pointed value.
So what I want to know if it's possible to have a IConvPtr object that
could be assigned any kind of pointer and that would allow to have a
custom action when assigning from a const char*.
Do I need to write a assignement overload for every type that can be
assigned ?
Could templated class could be of any help ?
class IConvPtr
{
public:
IConvPtr(void* pVoidVal):m_ptr(pVoidVal)
{
;
}
IConvPtr& IConvPtr::operator=(void* pVoidVal) {m_ptr = pVoidVal; return
*this;}
IConvPtr& IConvPtr::operator=(CEBLOB* pBlobVal) {m_ptr = pBlobVal;
return *this;}
IConvPtr& IConvPtr::operator=(USHORT* pusVal) {m_ptr = pusVal; return
*this;}
IConvPtr& IConvPtr::operator=(wchar_t* pWStringVal)
{
// Do something specific
return *this;
}
operator void *()
{
Now I am trying with a templated option :
template <typename T>
class IConvPtr
{
public:
IConvPtr(T pVal) : m_ptr(pVal)
{}
IConvPtr& IConvPtr::operator=(T aptr)
{
m_ptr = aptr;
}
operator void *()
{
return m_ptr;
}
private:
void* m_ptr;
};
template <>
class IConvPtr<wchar_t *>
{
public:
IConvPtr& IConvPtr::operator=(wchar_t* aptr)
{
// Specific stuff
m_ptr = aptr;
}
private:
void* m_ptr;
};
and I am testing like that :
switch( gynPropVal->ulPropType )
{
case CEVT_LPWSTR: { pRet = IConvPtr<wchar_t *> (lpProp->val.lpwstr)
;break; }
case CEVT_UI4: { pRet = IConvPtr<USHORT *> (&(lpProp->val.uiVal))
;break; }
default: { pRet = (void*)0 ;break; }
}
but I get the following error :
error C2440: '<function-style-cast>' : cannot convert from 'wchar_t*
*' to 'IConvPtr<wchar_t*>'
1> No constructor could take the source type, or constructor
overload resolution was ambiguous
and this is normal because it's not a wchar_t* * but a wchar_t* and if I
change the template to with a pointer syntax it doesn't help.
Now seems to work but I don't know why I don't like it again ...
// For any type do only an assignment
template <typename T>
class IConvPtr
{
public:
IConvPtr(T pVal) : m_ptr(pVal)
{
;
}
IConvPtr& IConvPtr::operator=(T aptr)
{
m_ptr = aptr;
}
operator void *()
{
return m_ptr;
}
private:
void* m_ptr;
};
// If assign from a wchar_t do something special
template <>
class IConvPtr<wchar_t*>
{
public:
IConvPtr(wchar_t* pVal)
{
// Specific stuff
m_ptr = pVal;
}
IConvPtr& IConvPtr::operator=(wchar_t* aptr)
{
// Specific stuff
m_ptr = aptr;
}
operator void *()
The first sentence of your post said you wanted to convert Windows
Unicode to UTF-8. Can you really blame him for interpreting your
question differently than you meant? He was trying to be helpful.
Anyway, the following does (I think) what you want. It specializes on
int* instead of wchar_t*, however. Minor detail. I'm sure you
understand the idea. Use the template on the function, not the class,
then provide a specialization.
--Jonathan
#include <iostream>
using std::cout;
using std::endl;
class IConvPtr {
void* m_ptr;
public:
IConvPtr() : m_ptr(0) {}
operator void *() { return m_ptr; }
IConvPtr& operator=(int* n) {
cout << "HWhat!?" <<endl;
m_ptr = 0;
return *this;
}
template <typename T>
IConvPtr& operator=(T aptr) {
m_ptr = aptr;
return *this;
}
};
int main() {
int a = 0;
long b = 1;
IConvPtr c;
c = &b;
cout << (void*)c << endl;
c = &a;
cout << (void*)c << endl;
return 0;
}
Deal with it, gynecology boy.
> Vincent R a �crit :
>>
>> So here is my question asked differently :
>>
>> in C++ (I insist) is it possible to write a kind of smart pointer
>> that when assigned from any type just copy the pointer EXCEPT when
>> it's a given type (for instance chat*).
>>
>> something that would allow me to write :
>>
>> IConvPtr iconvptr;
>>
>> ...
>> switch(ulPropType)
>> {
>> case TYPE_INT: { iconvPtr = &(lpProp->val.iValue); break; }
>> case TYPE_FLOAT: { iconvPtr = &(lpProp->val.fValue); break; }
>> case TYPE_STRING: { iconvPtr = &(lpProp->val.szValue); break; }
>> ...
>> }
>>
>> iconvPtr.getPtr()
Stripping out all that windows stuff certainly helped your question,
because now I can understand what you are asking about. (And it is
indeed not OS-specific.)
>>
>>
>> so now don't tell me it's windows specific, ulProptype is a unsigned
>> long that tell me the type of the pointed value.
>> So what I want to know if it's possible to have a IConvPtr object
>> that could be assigned any kind of pointer and that would allow to
>> have a custom action when assigning from a const char*.
Yes, it is possible to write such a class, but there are a few issues
you need to contend with.
The most important one is *ownership*: As your class contains a pointer
to some data, who will be responsible for cleaning up that data when you
are done with it? Does this answer change for the types that need a
custom action?
Another one is copying of the IConvPtr object. Would that be allowed or
not? If allowed, should copying create a deep copy (i.e. also copy the
data pointed to)?
>> Do I need to write a assignement overload for every type that can be
>> assigned ?
No, you can write a templated operator= for the general case and provide
specific overloads for the types that need custom treatment.
>> Could templated class could be of any help ?
It could, but I wouldn't bother.
>>
> Finally I did this but I find it ugly because I have to explicitly
> write code for each type I am assiging...
>
> class IConvPtr
> {
> public:
> IConvPtr(void* pVoidVal):m_ptr(pVoidVal)
> {
> ;
> }
You might want an additional constructor
IConvPtr(wchar_t* pWstringVal)
{
// do your special thing
}
>
> IConvPtr& IConvPtr::operator=(void* pVoidVal) {m_ptr = pVoidVal;
> return *this;}
>
> IConvPtr& IConvPtr::operator=(CEBLOB* pBlobVal) {m_ptr = pBlobVal;
> return *this;}
>
> IConvPtr& IConvPtr::operator=(USHORT* pusVal) {m_ptr = pusVal; return
> *this;}
You can collapse the assignment operators above into
template <typename T>
IConvPtr& operator=(T* pVal) { m_ptr = pVal; return *this; }
>
> IConvPtr& IConvPtr::operator=(wchar_t* pWStringVal)
> {
> // Do something specific
> return *this;
> }
> operator void *()
> {
> return m_ptr;
> }
>
>
> private:
> void* m_ptr;
> };
Bart v Ingen Schenau
--
a.c.l.l.c-c++ FAQ: http://www.comeaucomputing.com/learn/faq
c.l.c FAQ: http://c-faq.com/
c.l.c++ FAQ: http://www.parashift.com/c++-faq-lite/