How to send CString through sockets? - sockets

I'm trying to program a chatting program.
I ask you guys for help since I have little problem.
when I try to send a CString formatted strings, it only receives first letter of the string.
I'm using CAsyncSocket for sockets.
I tried it with char* format string, it worked.
Can you guys tell me what is wrong?
My code is like below:
worked.
char* buf = new char[m_strMsg.GetLength()];
buf = "helloworld!";
m_ClientSocket.Send("sended", m_strMsg.GetLength());
m_ClientSocket.Send(buf, 10);
not worked.
CString a = _T("helloworld!");
m_ClientSocket.Send(a,10);
I've also tried:
CString a = _T("helloworld!");
char* buf = new char[a.GetLength()];
buf = (LPSTR)(LPCTSTR)a;
m_ClientSocket.Send(buf,a.GetLength()];

Here is the proper UNICODE-compliant way of doing it:
CStringW sMessage = L"Hello World";
// convert from UTF-16 (UCS-2) to UTF-8
CStringA sMessageA = CW2A(sMessage, CP_UTF8);
const size_t nBytes = sizeof(CStringA::XCHAR) * sMessageA.GetLength();
CByteArray Message;
Message.SetSize( nBytes );
std::memcpy( Message.GetData(), (const BYTE*)(LPCSTR)sMessageA, nBytes );
m_ClientSocket.Send(Message.GetData(), Message.GetSize());

Related

QString encoding with special character

I m trying to convert QString with special character to const char but I did not succeed.
my function is:
void class::func(const QString& fileName) // fileName = "â.tmp"
{
qDebug()<< fileName; // display "â.tmp"
const char* cfileName = fileName.toAscii().data();
qDebug() << cfileName; // display "a?.tmp"
}
qDebug()<< fileName display the true value that is "â.tmp" but after converting it to const a char*, I do not succeed to have the right value.
In the second time I try to use
const char* cfileName = QString::fromUtf8(fileName.toAscii().data());
but I did not still have the right value, it display the same thing: a?.tmp.
How can I fix this?
ASCII character set does not have the character â, so what you are trying to do is impossible.
You could try this:
const char* cfileName = = fileName.toUtf8().data();

AudioFileWriteBytes fails with error code -40

I'm trying to write raw audio bytes to a file using AudioFileWriteBytes(). Here's what I'm doing:
void writeSingleChannelRingBufferDataToFileAsSInt16(AudioFileID audioFileID, AudioConverterRef audioConverter, ringBuffer *rb, SInt16 *holdingBuffer) {
// First, figure out which bits of audio we'll be
// writing to file from the ring buffer
UInt32 lastFreshSample = rb->lastWrittenIndex;
OSStatus status;
int numSamplesToWrite;
UInt32 numBytesToWrite;
if (lastFreshSample < rb->lastReadIndex) {
numSamplesToWrite = kNumPointsInWave + lastFreshSample - rb->lastReadIndex - 1;
}
else {
numSamplesToWrite = lastFreshSample - rb->lastReadIndex;
}
numBytesToWrite = numSamplesToWrite*sizeof(SInt16);
Then we copy the audio data (stored as floats) to a holding buffer (SInt16) that will be written directly to the file. The copying looks funky because it's from a ring buffer.
UInt32 buffLen = rb->sizeOfBuffer - 1;
for (int i=0; i < numSamplesToWrite; ++i) {
holdingBuffer[i] = rb->data[(i + rb->lastReadIndex) & buffLen];
}
Okay, now we actually try to write the audio from the SInt16 buffer "holdingBuffer" to the audio file. The NSLog will spit out an error -40, but also claims that it's writing bytes. No data is written to file.
status = AudioFileWriteBytes(audioFileID, NO, 0, &numBytesToWrite, &holdingBuffer);
rb->lastReadIndex = lastFreshSample;
NSLog(#"Error = %d, wrote %d bytes", status, numBytesToWrite);
return;
What is this error -40? By the way, everything works fine if I write straight from the ringBuffer to the file. Of course it sounds like junk, because I'm writing floats, not SInt16s, but AudioFileWriteBytes doesn't complain.
The key is to explicitly change the endianness of the incoming data to big endian. All I had to do was wrap CFSwapInt16HostToBig around my data to get:
float audioVal = rb->data[(i + rb->lastReadIndex) & buffLen];
holdingBuffer[i] = CFSwapInt16HostToBig((SInt16) audioVal );

Drawing currency symbol

How to draw a currency symbol in a custom label using CGContextShowTextAtPoint method in draw rect.
Here the symbol is in string format.
Any help!!
Thanks
You have to resort to C style strings, since this is what CGContextShowTextAtPoint() requires. In order to correctly handle the locale (the currency symbol changes with the locale) you must use setlocale(), then you format your string using strfmon() and finally you pass the string created with strfmon() to CGContextShowTextAtPoint().
Documentation is available as follows from the terminal:
man 3 setlocale
man 3 strfmon
EDIT/UPDATE: For your information, strfmon() internally uses struct lconv. The structure can be retrieved with the function localeconv(). See man 3 localeconv for a detailed description of the fields available in the structure.
for instance, try the following simple C program setting different locales
#include <stdio.h>
#include <locale.h>
#include <monetary.h>
int main(void)
{
char buf[BUFSIZ];
double val = 1234.567;
/* use your current locale */
setlocale(LC_ALL, "");
/* uncomment the next line and try this to use italian locale */
/* setlocale(LC_ALL, "it_IT"); */
strfmon(buf, sizeof buf, "You owe me %n (%i)\n", val, val);
fputs(buf, stdout);
return 0;
}
The following uses localeconv():
#include <stdio.h>
#include <limits.h>
#include <locale.h>
int main(void)
{
struct lconv l;
int i;
setlocale(LC_ALL, "");
l = *localeconv();
printf("decimal_point = [%s]\n", l.decimal_point);
printf("thousands_sep = [%s]\n", l.thousands_sep);
for (i = 0; l.grouping[i] != 0 && l.grouping[i] != CHAR_MAX; i++)
printf("grouping[%d] = [%d]\n", i, l.grouping[i]);
printf("int_curr_symbol = [%s]\n", l.int_curr_symbol);
printf("currency_symbol = [%s]\n", l.currency_symbol);
printf("mon_decimal_point = [%s]\n", l.mon_decimal_point);
printf("mon_thousands_sep = [%s]\n", l.mon_thousands_sep);
printf("positive_sign = [%s]\n", l.positive_sign);
printf("negative_sign = [%s]\n", l.negative_sign);
}
I don't really get what you're asking,
checking the documentation, the method would look something like that:
CGContextRef ctx = UIGraphicsGetCurrentContext();
const char *string = "$";
CGContextShowTextAtPoint (ctx, 160, 240, string, 1);
Haven't tested it, but this should draw $ in the center of the screen.
BTW, why not use images?
~ Natanavra.

How do I send XML as the email body from a native iPhone app?

I am writing an app that ultimately wants to send some XML via email.
I have the mailto/URL thing sussed, thanks to various links on the interweb, including Brandon and Simon Maddox.
So I can send emails with the xml formatted using square brackets ([ ]), rather than the usual angle brackets (< >). But when I send angle brackets, with the XML mangled using the stringByAddingPercentEscapesUsingEncoding call, It treats it as HTML and just prints the values.
If change them to "& lt;" and "& gt;" then it totally strips the XML out... (I know there should not be a space after the & - but the SO formatter turns them into <,>...)
I tried adding some HTML in front to see if that helped, to no avail.
I don't suppose anyone has done this?
Perhaps in-app email is the easy route for me to go... must look into that.
Thanks in advance.
The following code worked for me... I have SIP message data containing <> that needed escaping.
/* remember to call urlEscapeStringDone to free the malloced string.. */
char *urlEscapeString(char *str)
{
int i, l;
char *escStr;
escStr = malloc(strlen(str)*3 + 1);
if(!escStr) return NULL;
memset(escStr, 0, strlen(str)*3);
l = strlen(escStr);
for(i = 0; i < strlen(str); i++)
{
char c = str[i];
/* < and > handling for HTML interpreters.. (apple mail) */
if(c == '<')
{
strcat(escStr, "%26lt%3b");
l += 8;
}
else if(c == '>')
{
strcat(escStr, "%26gt%3b");
l += 8;
}
else if(must_escape(c))
{
char tmp[3];
sprintf(tmp, "%02x", (unsigned) c);
escStr[l] = '%'; l++;
escStr[l] = tmp[0]; l++;
escStr[l] = tmp[1]; l++;
}
else
{
escStr[l] = str[i];
l++;
}
}
printf("escaped: %s\n", escStr);
return escStr;
}
void urlEscapeStringDone(char *str)
{
if(str) free(str);
}
int must_escape(char c)
{
char *allowedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789._";
if(!strchr(allowedChars, c)) return 1;
return 0;
}
Did you try replacing all the '<' and '>' characters with '&lt' and '&gt' after you had wrapped it in the basic HTML headers?
As I understand it, this is the usual technique to display XML on a web page.

Parsing email "Received:" headers

We need to parse Received: email headers according to RFC 5321. We need to extract domains or IPs through which the mail has traversed. Also, we need to figure out if an IP is an internal IP.
Is there already a library which can help out, preferably in C\C++?
For example:
Received: from server.mymailhost.com (mail.mymailhost.com [126.43.75.123])
by pilot01.cl.msu.edu (8.10.2/8.10.2) with ESMTP id NAA23597;
Fri, 12 Jul 2002 16:11:20 -0400 (EDT)
We need to extract the "by" server.
The format used by 'Received' lines is defined in RFC 2821, and regex can't parse it.
(You can try anyway, and for a limited subset of headers produced by known software you might succeed, but when you attach this to the range of strange stuff found in real-world mail it will fail.)
Use an existing RFC 2821 parser and you should be OK, but otherwise you should expect failure, and write the software to cope with it. Don't base anything important like a security system around it.
We need to extract the "by" server.
'from' is more likely to be of use. The hostname given in a 'by' line is as seen by the host itself, so there is no guarantee it will be a publically resolvable FQDN. And of course you don't tend to get valid (TCP-Info) there.
There is a Perl Received module which is a fork of the SpamAssassin code. It returns a hash for a Received header with the relevant information. For example
{ ip => '64.12.136.4',
id => '875522',
by => 'xxx.com',
helo => 'imo-m01.mx.aol.com' }
vmime should be fine, moreless any mail library will allow you to do that.
You'll want to use Regular Expressions possibly
(?<=by).*(?=with)
This will give you pilot01.cl.msu.edu (8.10.2/8.10.2)
Edit:
I find it amusing that this was modded down when it actually gets what the OP asked for.
C#:
string header = "Received: from server.mymailhost.com (mail.mymailhost.com [126.43.75.123]) by pilot01.cl.msu.edu (8.10.2/8.10.2) with ESMTP id NAA23597; Fri, 12 Jul 2002 16:11:20 -0400 (EDT)";
System.Text.RegularExpressions.Regex r = new System.Text.RegularExpressions.Regex(#"(?<=by).*(?=with)");
System.Text.RegularExpressions.Match m = r.Match(header);
Console.WriteLine(m.Captures[0].Value);
Console.ReadKey();
I didnt claim that it was complete, but am wondering if the person that gave it a -1 even tried. Meh..
You can use regular expressions. It would look like this(not tested):
#include <regex.h>
regex_t *re = malloc(sizeof(regex_t));
const char *restr = "by ([A-Za-z.]+) \(([^\)]*)\)";
check(regcomp(re, restr, REG_EXTENDED | REG_ICASE), "regcomp");
size_t nmatch = 1;
regmatch_t *matches = malloc(sizeof(regmatch_t) * nmatch);
int ret = regexec(re, YOUR_STRING, nmatch, matches, 0);
check(ret != 0, "regexec");
int size;
size = matches[2].rm_eo - matches[2].rm_so;
char *host = malloc(sizeof(char) * size);
strncpy(host, YOUR_STRING + matches[2].rm_so, size );
host[size] = '\0';
size = matches[3].rm_eo - matches[3].rm_so;
char *ip = malloc(sizeof(char) * size);
strncpy(ip, YOUR_STRING + matches[3].rm_so, size );
ip[size] = '\0';
check is a macro to help you figure out if there are any problems:
#define check(condition, description) if (condition) { fprintf(stdout, "%s:%i - %s - %s\n", __FILE__, __LINE__, description, strerror(errno)); exit(1); }
typedef struct mailHeaders{
char name[100];
char value[2000];
}mailHeaders;
int header_count = 0;
mailHeaders headers[30]; // A struct to hold the name value pairs
char *GetMailHeader(char *name)
{
char *value = NULL;;
int i;
for(i=0;i<header_count;i++){
if(strcmp(name,headers[i].name) == 0){
value = headers[i].value;
break;
}
}
return(value);
}
void ReadMail(void)
{
//Loop through the email message line by line to separate the headers. Then save the name value pairs to a linked list or struct.
char *Received = NULL // Received header
char *mail = NULL; // Buffer that has the email message.
char *line = NULL; // A line of text in the email.
char *name = NULL; // Header name
char *value = NULL; // Header value
int index = -1; // Header index
memset(&headers,'\0',sizeof(mailHeaders));
line = strtok(mail,"\n");
while(line != NULL)
{
if(*line == '\t') // Tabbed headers
{
strcat(headers[index].value,line); // Concatenate the tabbed values
}
else
{
name = line;
value = strchr(line,':'); // Split the name value pairs.
if(value != NULL)
{
*value='\0'; // NULL the colon
value++; // Move the pointer past the NULL character to separate the name and value
index++;
strcpy(headers[index].name,name); // Copy the name to the data structure
strcpy(headers[index].value,value); // Copy the value to the data structure
}
}
if(*line == '\r') // End of headers
break;
line = strtok(NULL,"\n"); // Get next header
header_count = index;
}
Received = GetMailHeader("Received");
}
It is not difficult to parse such headers, even manually line-by-line. A regex could help there by looking at by\s+(\w)+\(. For C++, you could try that library or that one.
Have you considered using regular expressions?
Here is a list of internal, non-routable address ranges.