TAPI lineGetAddressID() fails with LINEERR_INVALADDRESS - c++

I have a windows mobile 6 application using TAPI 2.0. lineGetAddressID() is needed to get the address identifier used by several calls in the telephone api, but I can't get it to work.
I have tried the following to no avail:
HLINE line; // valid handle from lineOpen();
DWORD addr_id = 0;
result = ::lineGetAddressID( line, &addr_id, LINEADDRESSMODE_DIALABLEADDR, L"1234", 5 );
result = ::lineGetAddressID( line, &addr_id, LINEADDRESSMODE_DIALABLEADDR, L"5551234", 8 );
result = ::lineGetAddressID( line, &addr_id, LINEADDRESSMODE_DIALABLEADDR, L"1115551234", 11 );
result = ::lineGetAddressID( line, &addr_id, LINEADDRESSMODE_DIALABLEADDR, L"11115551234", 12 );
All of them return LINEERR_INVALADDRESS. Can anybody point out what I may be doing wrong?
As a side question, how can I programmaticly get the address? It appears in the LINEADDRESSCAPS structure returned by lineGetAddressCaps(), but that requires an address identifier (which would need to come from lineGetAddressID(), which requires an address...).
Note: I realize I could use 0 as the address ID and it will probably work, but I have no guarantee it will work for every platform. I would like to get this solved 'right'.
Thanks,
PaulH

When you invoke lineGetDevCaps one of the members of the LINEDEVCAPS structure, dwNumAddresses, is a count of the number of addresses associated with the line device.
TAPI states that the value of address identifiers are defined as the following:
Address identifiers range from zero to one less than the value indicated by dwNumAddresses.
So you can iterate through each address identifier value in the range [0 .. (dwNumAddresses - 1)] and invoke lineGetAddressCaps as you have provided a valid address identifier. There is no need to use lineGetAddressID in this case as the address identifier is known and valid.
If you do this, do any of the addresses specified in the LINEADDRESSCAPS structure match the string being used in your calls to lineGetAddressID? Noting that your application is configured to use Unicode rather than ANSI.

Related

Problem with receiving mails from the SENT folder

if ( IdIMAP1->SelectMailBox( "SENT" ) )
{
TIdIMAP4SearchRec sr[1];
sr[0].SearchKey = skAll;
IdIMAP1->UIDSearchMailBox( EXISTINGARRAY(sr) );
int ile = IdIMAP1->MailBox->SearchResult.Length;
}
Error:
First chance exception at $757BF192. Exception class EIdReadLnMaxLineLengthExceeded with message 'Max line length exceeded.'.
It tries to read messages from the SENT folder and the program throws an error. There is no error when receiving from another SENT subfolder.
It seems to me that the problem lies in specifying SearchKey when the value is set to skAll, but no other setting reads the email despite the lack of an error. What does this error mean and how can I fix it?
By the way, I have a question about the SearchKey settings. Is it possible to give a specific date here that would filter emails only from today, for example?
Error:
First chance exception at $757BF192. Exception class EIdReadLnMaxLineLengthExceeded with message 'Max line length exceeded.'.
... What does this error mean and how can I fix it?
It means TIdIMAP4 called the IOHandler.ReadLn() method and received more than 16K worth of data that had no line breaks in it. The default value of the IOHandler.MaxLineLength property is 16384, and the default value of the IOHandler.MaxLineAction is maException.
To workaround the error, you could try increasing the value of the MaxLineLength (say, to MaxInt). However, a proper fix would be to prevent such a large amount of undelimited data to be received in the first place.
The response of UIDSearchMailBox() is a single line containing a list of email sequence numbers delimited by spaces, so you could be getting the EIdReadLnMaxLineLengthExceeded error here if the search is producing a LOT of sequence numbers (say, thousands of them, which makes sense when searching for just skAll on a large mailbox).
You really should not be searching for just skAll by itself to begin with. If you want to access all emails in the mailbox, just iterate the mailbox instead. After SelectMailBox() returns success, TIdIMAP4.MailBox.TotalMsgs will contain the number of emails currently in the mailbox. You can then run a loop retrieving individual emails as needed using sequence numbers in the range of 1..TotalMsgs, inclusive.
Otherwise, filter your search criteria better to produce fewer results.
By the way, I have a question about the SearchKey settings. Is it possible to give a specific date here that would filter emails only from today, for example?
Yes, of course. Look at the TIdIMAP4SearchKey enum, it lists all of the different keys you can search on, for instance:
skOn, //Messages whose internal date is within the specified date.
skSentOn, //Messages whose [RFC-822] Date: header is within the specified date.
skSentSince, //Messages whose [RFC-822] Date: header is within or later than the specified date.
skSince, //Messages whose internal date is within or later than the specified date.
In this case, either of those should work, depending on whether you want to search the email's internal server timestamps or their Date headers, eg:
if ( IdIMAP1->SelectMailBox( "SENT" ) )
{
TIdIMAP4SearchRec sr[1];
sr[0].SearchKey = skSince;
sr[0].Date = Sysutils::Date(); // or Dateutils::Today()
IdIMAP1->UIDSearchMailBox( EXISTINGARRAY(sr) );
int ile = IdIMAP1->MailBox->SearchResult.Length;
}
UPDATE
this example refer to expresion 'later than the specified date' but I can see that it is possible to use 'within'. How to set range of data? Is it possible in SearchKey settings?
There is no 'within' search key in IMAP. If you are referring to RFC 5032: WITHIN Search Extension to the IMAP Protocol (the OLDER and YOUNGER search keys), then TIdIMAP4 does not implement this extension at this time. I have opened a ticket to add it in a future release:
#420: Update TIdIMAP4 to support RFC 5032: "WITHIN Search Extension to the IMAP Protocol"
In the meantime, you can combine multiple search keys and they will be logically AND'ed together, eg:
if ( IdIMAP1->SelectMailBox( "SENT" ) )
{
TDateTime dtNow = Sysutils::Now();
TIdIMAP4SearchRec sr[2];
sr[0].SearchKey = skSince;
sr[0].Date = Dateutils::StartOfTheDay(Dateutils::IncDay(dtNow, -6));
sr[1].SearchKey = skBefore;
sr[1].Date = dtNow;
IdIMAP1->UIDSearchMailBox( EXISTINGARRAY(sr) );
int ile = IdIMAP1->MailBox->SearchResult.Length;
}
I suggest you read RFC 3501 Section 6.4.4 for how the SEARCH command works and what the standard search keys are.

Why does glBindBuffer has a unsigned int as its second parameter?

As far as I know , I need to firstly generate a buffer's name by calling glGenBuffers , which allocates some RAMs to a specific object(array) named by developer manually . That's why I need to write codes in the form of 'glGenBuffers(int, actually address)'. So whereby , if I want to give some RAMs a specific usage , I need to call glBindBuffer , attributing the target 'usage' to the first parameter , the RAMs to the second parameter .
That's the problem . Why should I attribute an int value to this second parameter?
Isn't a specific address like &xxx ?
Just like what I have done in glGenBuffers : confirm an area where the buffer datas should be stored.
Does glBindBuffer locate the certain address in its body automatically, but doesn't require developers to type in a pointer ?
glGenBuffers chooses a bunch of ID numbers for buffers, then stores the ID numbers into your variable. glBindBuffers selects one of the buffers based on its ID number. You don't get to see the addresses of any buffers.

Machine ID Code in C++

I tried this because I want to learn how to grab a machine unique ID.
I need it because I'm gonna code a program that reads the machineid and compares it to a specific one.
I edited the code(in the end, the code that prints the Machine ID) to this:
string MachineID;
MachineID = vtProp.bstrVal;
if (MachineID == vtProp.bstr)
but it only gives me this error.
How would I make my HWID variable be set to the value of vtProp.bstrVal, then compare it with vtProp.bstrVal? I've googled for some hour now, can't seem to get it fixed.
Thanks in advance!
Simple syntax error - you've used =, which is assignment, instead of ==, which is comparison.
Because c++ accepts nonboolean types in if statements, the code if(variable = value) is acceptable to the compiler, which tries to assign MachineID the value of vtProp.bstr, which causes your error due to type mismatch.

HOW to get value stored in a python variable if only its address is given?

If a variable has address '20754060', how can we get the value stored in that address?
a=20754060 #consist of address of some variable
how can we get value stored in '20754060' location
You probably cannot, and even if you can - you really shouldn't. Screwing around with memory content, ignoring or standing in way of GC is WRONG and probably will cause some weird errors.
As people already mentioned: this is so wrong ;)
However, this is how you do it (just a start).
from ctypes import *
# create c_int (only ctype addresses work)
a = c_int(423)
# get address of a
address = addressof(a)
#print address (just for fun)
print address
# print content of address (this works for size 1)
print c_char_p(address)
#check that it is the same (423 is 1a7 in hex. Note MSB vs LSB)
print hex(423)
This prints out:
35746280
c_char_p('\xa7\x01')
0x1a7
The above works only in the case of ctype objects like c_int (=ctypes.c_int).
c_char_p function gets the values one byte at the time. For more complicated objects, things get really ugly really fast and probably there is a limit at some point. But if you want, start reading here:
http://docs.python.org/3/library/ctypes.html
try this, in my case it is working.
address = id(variable)
this gives the id of the variable, and use this id to check the value of the variable
ctypes.cast(address, ctypes.py_object).value

Create/Initialize new object using variables

I am intending to initialize or create a new object using variables.
The error says that i am conflicting declaration.
//instantiate new node object***********************
string peer = "peer";
string pNo = convertInt(addPeerNum); //convert peer number to string to concatenate 2 strings
string NewPeerObject = peer+pNo; << ERROR POINTS TO HERE
nodes NewPeerObject; << ERROR POINTS TO HERE
Error message:
conflicting declaration 'nodes NewPeerObject' <-- last line of error
'NewPeerObject' has a previous declaration as 'string NewPeerObject' <-- 2nd last line
My main point is to create a new object when I add more peers.
If I addpeer 1, it will create a new object 'peer1'
If I addpeer 2, it will be 'peer2' etc.
I am reading in the file which contains
addpeer 1
addpeer 100
addpeer 28
In my program, it reads the file and stores the number in a variable called 'addPeerNum'
and with me doing this, it actually has a different string content of 'NewPeerObject'.
So in this instance, i am actually trying to create 3 new objects.
Is there any way which i will be able to do it?
You cannot have two objects with same name like that. It violates the One definition Rule, naturally the compiler complains.
Just please do yourself a favor and change the name of either of them.
I think that what you are looking for is a kind of dynamically resized array of your objects.
You can use std::list to achieve that kind of behavior.
std::list<PeerObject> list;
PeerObject peer(peer_string);
list.insert(peer);
or a std::map if you want to use your peer string as a key
std::map<std::string, PeerObject> peer_map;
PeerObject peer(peer_string);
peer_map.insert(peer_string, peer);
// .... add more
PeerObject& foundObj = peer_map[a_key];
foundObj.doSomething();
You could also do it with MACROs but only at compile time and you should avoid them if possible.