object used to convert a pointer to a c string

V

Vincent R

Hi,

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::eek:perator=(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.
 
A

Alf P. Steinbach

* Vincent R:

Hi! :)
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
}

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::eek:perator=(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
 
V

Vincent R

Alf P. Steinbach a écrit :
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



That also seems pretty irrelevant to your question.



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.


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.

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 ?
 
V

Vincent R

Vincent R a écrit :
Alf P. Steinbach a écrit :

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 ?
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)
{
;
}

IConvPtr& IConvPtr::eek:perator=(void* pVoidVal) {m_ptr = pVoidVal; return
*this;}

IConvPtr& IConvPtr::eek:perator=(CEBLOB* pBlobVal) {m_ptr = pBlobVal;
return *this;}

IConvPtr& IConvPtr::eek:perator=(USHORT* pusVal) {m_ptr = pusVal; return
*this;}

IConvPtr& IConvPtr::eek:perator=(wchar_t* pWStringVal)
{
// Do something specific
return *this;
}
operator void *()
{
return m_ptr;
}


private:
void* m_ptr;
};
 
V

Vincent R

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)
{
;
}

IConvPtr& IConvPtr::eek:perator=(void* pVoidVal) {m_ptr = pVoidVal;
return *this;}

IConvPtr& IConvPtr::eek:perator=(CEBLOB* pBlobVal) {m_ptr = pBlobVal;
return *this;}

IConvPtr& IConvPtr::eek:perator=(USHORT* pusVal) {m_ptr = pusVal;
return *this;}

IConvPtr& IConvPtr::eek:perator=(wchar_t* pWStringVal)
{
// Do something specific
return *this;
}
operator void *()
{
return m_ptr;
}


private:
void* m_ptr;
};

Now I am trying with a templated option :

template <typename T>
class IConvPtr
{
public:
IConvPtr(T pVal) : m_ptr(pVal)
{}

IConvPtr& IConvPtr::eek:perator=(T aptr)
{
m_ptr = aptr;
}

operator void *()
{
return m_ptr;
}

private:
void* m_ptr;
};

template <>
class IConvPtr<wchar_t *>
{
public:
IConvPtr& IConvPtr::eek:perator=(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.
 
V

Vincent R

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::eek:perator=(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::eek:perator=(wchar_t* aptr)
{
// Specific stuff
m_ptr = aptr;
}

operator void *()
{
return m_ptr;
}
private:
void* m_ptr;
};
 
J

Jonathan Lee

I am really pissed off by that kind of answers, my question is not
windows specific.

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;
}
 
S

Squeamizh

Alf P. Steinbach a écrit :

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.

Deal with it, gynecology boy.
 
B

Bart van Ingen Schenau

Vincent said:
Vincent R a écrit :

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.)

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)?

No, you can write a templated operator= for the general case and provide
specific overloads for the types that need custom treatment.

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::eek:perator=(void* pVoidVal) {m_ptr = pVoidVal;
return *this;}

IConvPtr& IConvPtr::eek:perator=(CEBLOB* pBlobVal) {m_ptr = pBlobVal;
return *this;}

IConvPtr& IConvPtr::eek:perator=(USHORT* pusVal) {m_ptr = pusVal; return
*this;}

You can collapse the assignment operators above into
IConvPtr& IConvPtr::eek:perator=(wchar_t* pWStringVal)
{
// Do something specific
return *this;
}
operator void *()
{
return m_ptr;
}


private:
void* m_ptr;
};

Bart v Ingen Schenau
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top