Results 1 to 14 of 14

Thread: unable to save QCStrings properly in a buffer

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Jul 2006
    Posts
    79
    Qt products
    Qt3 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: unable to save QCStrings properly in a buffer

    aha! so i managed to do thesaving part properly but now i am having trouble with doing the inverse, that is reading from the shared memory the strings.
    i thought that the idea was:
    read the lengths of each string
    memcpy all the string to a char* all_the_strings variable,
    and then declare as many char* variables as there are strings (preknown) and
    memcpy each_strings_length characters from the all_the_strings variable
    to each separate char *...
    here is how i mplemented that:

    Qt Code:
    1. void readingTheShMem()
    2. {
    3. int tOTL=0;
    4. int tONL=0;
    5. int tSNL=0;
    6. int tSLL=0;
    7. int tIDL=0;
    8. int tMDL=0;
    9. int readingLength;
    10.  
    11. //lock the file for writing
    12. memset (&lock, 0, sizeof(lock));
    13. lock.l_type = F_WRLCK;
    14. fcntl (fd, F_SETLKW, &lock);
    15.  
    16. struct ShMem *infoVar=(ShMem*)((char*)file_memory);
    17.  
    18. tOTL = infoVar->oTL;
    19. tONL = infoVar->oNL;
    20. tSNL = infoVar->sNL;
    21. tSLL = infoVar->sLL;
    22. tIDL = infoVar->iDL;
    23. tMDL = infoVar->mDL;
    24. readingLength = tOTL + tONL + tSNL + tSLL + tIDL + tMDL ;
    25. char *readingStrs[readingLength];
    26. printf("reading length = %d\n", readingLength);
    27. printf("the infoVar->oAndS_str reading points to=%p\n",&(infoVar->oAndS_str));
    28. memcpy(readingStrs, &(infoVar->oAndS_str), readingLength);
    29.  
    30. //unlock the file to allow access
    31. lock.l_type = F_UNLCK;
    32. fcntl (fd, F_SETLKW, &lock);
    33.  
    34. char *tOT[tOTL]; memcpy(tOT,readingStrs,tOTL);
    35. printf("tOTL = %d and oT ptr = %p\n", tOTL, readingStrs);
    36. char *tON[tONL]; memcpy(tON,(readingStrs+tOTL),tONL);
    37. printf("tONL = %d and oN ptr = %p\n", tONL, (readingStrs+tOTL));
    38. char *tSN[tSNL]; memcpy(tSN,(readingStrs+tOTL+tONL),tSNL);
    39. printf("tSNL = %d and sN ptr = %p\n", tSNL, (readingStrs+tOTL+tONL));
    40. char *tSL[tSLL]; memcpy(tSL,(readingStrs+tOTL+tONL+tSNL),tSLL);
    41. printf("tSLL = %d and sL ptr = %p\n", tSLL, (readingStrs+tOTL+tONL+tSNL));
    42. char *tID[tIDL]; memcpy(tID,(readingStrs+tOTL+tONL+tSNL+tSLL),tIDL);
    43. printf("tIDL = %d and iD ptr = %p\n", tIDL, (readingStrs+tOTL+tONL+tSNL+tSLL));
    44. char tMD[tMDL]; memcpy(tMD,(readingStrs+tOTL+tONL+tSNL+tSLL+tIDL),tMDL);
    45. printf("tMDL = %d and mD ptr = %p\n", tMDL, (readingStrs+tOTL+tONL+tSNL+tSLL+tIDL));
    46.  
    47. printf("oT = %s\n",tOT);
    48. printf("oN = %s\n",tON);
    49. printf("sN = %s\n",tSN);
    50. printf("sL = %s\n",tSL);
    51. printf("iD = %s\n",tID);
    52. printf("mD = %s\n",tMD);
    53.  
    54. operatorTel = QString::fromLocal8Bit((const char*)tOT);
    55. operatorName = QString::fromLocal8Bit((const char*)tON);
    56. stationNum = QString::fromLocal8Bit((const char*)tSN);
    57. stationLoc = QString::fromLocal8Bit((const char*)tSL);
    58. installationDate = QString::fromLocal8Bit((const char*)tID);
    59. maintenanceDate = QString::fromLocal8Bit((const char*)tMD);
    60.  
    61. //do smth with these variables now
    62.  
    63. }
    To copy to clipboard, switch view to plain text mode 

    and the output i get

    Qt Code:
    1. reading length = 41
    2. the infoVar->oAndS_str reading points to = 0xb7736168
    3. tOTL = 8 and oT ptr = 0xbfcfa020
    4. tONL = 4 and oN ptr = 0xbfcfa168
    5. tSNL = 4 and sN ptr = 0xbfcfa20c
    6. tSLL = 5 and sL ptr = 0xbfcfa2b0
    7. tIDL = 10 and iD ptr = 0xbfcfa37d
    8. tMDL = 10 and mD ptr = 0xbfcfa517
    9. ϿПϿ�Ͽ ϿPϿ8hihi1234hello10/10/200022/22/2000;
    10. oN = |
    11. sN =
    12. sL = �h
    13. iD = Ͽ
    14. mD =
    To copy to clipboard, switch view to plain text mode 
    do you have any idea where my train of thinking is faulting?
    nass
    Last edited by nass; 14th November 2006 at 13:32.

  2. #2
    Join Date
    Jul 2006
    Posts
    79
    Qt products
    Qt3 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: unable to save QCStrings properly in a buffer

    i managed to read the right data from the buffer with printf, by making char readingStrs[readingLength] a proper variable (instead of a char *)..
    the funny thing is that in memcpy i am supposed to give pointers to parameters. but if i try to get a reference & of readingStrs, the code fails to execute correctly!!! why is that?

    here is the code

    Qt Code:
    1. void readFromShMem()
    2. {
    3. int tOTL=0;
    4. int tONL=0;
    5. int tSNL=0;
    6. int tSLL=0;
    7. int tIDL=0;
    8. int tMDL=0;
    9. int readingLength;
    10.  
    11. //lock the file for writing
    12. memset (&lock, 0, sizeof(lock));
    13. lock.l_type = F_WRLCK;
    14. fcntl (fd, F_SETLKW, &lock);
    15.  
    16. //struct cursStruct *cursVar=(cursStruct*)((char*)file_memory + 0x4);
    17. struct ShMem *infoVar=(ShMem*)((char*)file_memory);
    18.  
    19. tOTL = infoVar->oTL;
    20. tONL = infoVar->oNL;
    21. tSNL = infoVar->sNL;
    22. tSLL = infoVar->sLL;
    23. tIDL = infoVar->iDL;
    24. tMDL = infoVar->mDL;
    25. readingLength = tOTL + tONL + tSNL + tSLL + tIDL + tMDL ;
    26. char readingStrs[readingLength];
    27. printf("reading length = %d\n", readingLength);
    28. printf("the infoVar->oAndS_str reading points to = %p\n",&(infoVar->oAndS_str));
    29. memcpy(&readingStrs, &(infoVar->oAndS_str), readingLength);
    30. printf("readingStrs contains after = %s\n",readingStrs);
    31.  
    32. //unlock the file to allow access
    33. lock.l_type = F_UNLCK;
    34. fcntl (fd, F_SETLKW, &lock);
    35.  
    36. char tOT[tOTL]; memcpy(tOT,readingStrs,tOTL);
    37. printf("tOTL = %d and oT ptr = %p\n", tOTL, readingStrs);
    38. char tON[tONL]; memcpy(tON,(readingStrs+tOTL),tONL);
    39. printf("tONL = %d and oN ptr = %p\n", tONL, (readingStrs+tOTL));
    40. char tSN[tSNL]; memcpy(tSN,(readingStrs+tOTL+tONL),tSNL);
    41. printf("tSNL = %d and sN ptr = %p\n", tSNL, (readingStrs+tOTL+tONL));
    42. char tSL[tSLL]; memcpy(tSL,(readingStrs+tOTL+tONL+tSNL),tSLL);
    43. printf("tSLL = %d and sL ptr = %p\n", tSLL, (readingStrs+tOTL+tONL+tSNL));
    44. char tID[tIDL]; memcpy(tID,(readingStrs+tOTL+tONL+tSNL+tSLL),tIDL);
    45. printf("tIDL = %d and iD ptr = %p\n", tIDL, (readingStrs+tOTL+tONL+tSNL+tSLL));
    46. char tMD[tMDL]; memcpy(tMD,(readingStrs+tOTL+tONL+tSNL+tSLL+tIDL),tMDL);
    47. printf("tMDL = %d and mD ptr = %p\n", tMDL, (readingStrs+tOTL+tONL+tSNL+tSLL+tIDL));
    48.  
    49. //the printf's below output the right values on console
    50. printf("oT = %.8s.\n",tOT);
    51. printf("oN = %.4s.\n",tON);
    52. printf("sN = %.4s.\n",tSN);
    53. printf("sL = %.5s.\n",tSL);
    54. printf("iD = %.10s.\n",tID);
    55. printf("mD = %.9s.\n",tMD);
    56.  
    57. //but the QString values below do not output the right values when they are 'setText'd' in QLabels.
    58. operatorTel = QString::fromLocal8Bit((const char*)tOT);
    59. operatorName = QString::fromLocal8Bit((const char*)tON);
    60. stationNum = QString::fromLocal8Bit((const char*)tSN);
    61. stationLoc = QString::fromLocal8Bit((const char*)tSL);
    62. installationDate = QString::fromLocal8Bit((const char*)tID);
    63. maintenanceDate = QString::fromLocal8Bit((const char*)tMD);
    64.  
    65. }
    To copy to clipboard, switch view to plain text mode 

    so while i do have the right printfs, i get some reduntant chars on the QLAbels if i try to ->setText() one of the above QStrings in them...
    any ideas?

  3. #3
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    28
    Thanked 976 Times in 912 Posts

    Default Re: unable to save QCStrings properly in a buffer

    Quote Originally Posted by nass View Post
    the funny thing is that in memcpy i am supposed to give pointers to parameters. but if i try to get a reference & of readingStrs, the code fails to execute correctly!!! why is that?
    Because you can treat an array of chars just like a pointer to the first character. While &readingStrs is a pointer to an array (something more like char**, but not exactly).

    Quote Originally Posted by nass View Post
    //the printf's below output the right values on console
    printf("oT = %.8s.\n",tOT);
    ...
    These printfs work, because you have specified each string length in the format. Probably you forgot about the terminating NUL character.

    Luckily QString::fromLocal8Bit() has a second parameter and you can simply do this:
    Qt Code:
    1. operatorTel = QString::fromLocal8Bit( readingStrs, tOTL );
    2. operatorName = QString::fromLocal8Bit( readingStrs + tOTL, tONL);
    3. ...
    To copy to clipboard, switch view to plain text mode 

  4. #4
    Join Date
    Jul 2006
    Posts
    79
    Qt products
    Qt3 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: unable to save QCStrings properly in a buffer

    there is one final (hopefully!) problem i am having however. if i save greek chars on a QFile using streaming operations and re-read them i get ???? (as many ? as there where supposed to be greek chars).

    in the beginning i would get crazy QCString lengths (for 3 greek chars i'd get a length of 24 or smth), so i played around with QTextCodec abit and managed to make - at least measuring the length correctly - work. Then i remove from aQLabel->setText() the QString::fromLocal8Bit function and on saving and reading from shared memory the characters appear and work as expected. Here is the code that DOES work for the shared memory. Then i will post the write - read to QFile functions.

    here is the saving code for shared memory:
    the loc variable is QTextCodec * , declared as private variable in this form and initialized in init() as

    Qt Code:
    1. loc = QTextCodec::codecForName("ISO8859-7");//extended ASCII with greek
    2. loc->setCodecForCStrings(loc);
    To copy to clipboard, switch view to plain text mode 

    then the code is ..

    Qt Code:
    1. {
    2. QCString tOT = loc->fromUnicode(tempOperTel);
    3. QCString tON = loc->fromUnicode(tempOperName);
    4. QCString tSN = loc->fromUnicode(tempStatNum);
    5. QCString tSL = loc->fromUnicode(tempStatLoc);
    6. QCString tID = loc->fromUnicode(tempInstallDate);
    7. QCString tMD = loc->fromUnicode(tempMaintenDate);
    8.  
    9. //i have commented the lines below since they didn't show the greek characters
    10. //correctly
    11. /*QCString tOT = tempOperTel.local8Bit();
    12.   QCString tON = tempOperName.local8Bit();
    13.   QCString tSN = tempStatNum.local8Bit();
    14.   QCString tSL = tempStatLoc.local8Bit();
    15.   QCString tID = tempInstallDate.local8Bit();
    16.   QCString tMD = tempMaintenDate.local8Bit();*/
    17.  
    18. int tOTL = tOT.length();
    19. int tONL = tON.length();
    20. int tSNL = tSN.length();
    21. int tSLL = tSL.length();
    22. int tIDL = tID.length();
    23. int tMDL = tMD.length();
    24.  
    25. QCString tmp=tOT+tON+tSN+tSL+tID+tMD;
    26. const char *savingStrs = tmp;
    27. int savingLength = tmp.length() ;
    28.  
    29. //lock the file for writing
    30. memset (&lock, 0, sizeof(lock));
    31. lock.l_type = F_WRLCK;
    32. fcntl (fd, F_SETLKW, &lock);
    33.  
    34. *((char*)file_memory+wOpcodeOffset) = 9;
    35. struct ShMem *infoVar=(ShMem*)((char*)file_memory);
    36.  
    37. infoVar->oTL = tOTL;
    38. infoVar->oNL = tONL;
    39. infoVar->sNL = tSNL;
    40. infoVar->sLL = tSLL;
    41. infoVar->iDL = tIDL;
    42. infoVar->mDL = tMDL;
    43. memcpy(&(infoVar->oAndS_str), savingStrs, savingLength);
    44.  
    45. //unlock the file to allow access
    46. lock.l_type = F_UNLCK;
    47. fcntl (fd, F_SETLKW, &lock);
    48. }
    To copy to clipboard, switch view to plain text mode 

    and then i reuse the QTextCodec to read the data from the shared memory:
    the reading code for shared memory is:


    Qt Code:
    1. {
    2. int tOTL=0;
    3. int tONL=0;
    4. int tSNL=0;
    5. int tSLL=0;
    6. int tIDL=0;
    7. int tMDL=0;
    8. int readingLength;
    9.  
    10. //lock the file for writing
    11. memset (&lock, 0, sizeof(lock));
    12. lock.l_type = F_WRLCK;
    13. fcntl (fd, F_SETLKW, &lock);
    14.  
    15. struct ShMem *infoVar=(ShMem*)((char*)file_memory);
    16.  
    17. tOTL = infoVar->oTL;
    18. tONL = infoVar->oNL;
    19. tSNL = infoVar->sNL;
    20. tSLL = infoVar->sLL;
    21. tIDL = infoVar->iDL;
    22. tMDL = infoVar->mDL;
    23. readingLength = tOTL + tONL + tSNL + tSLL + tIDL + tMDL ;
    24. char readingStrs[readingLength];
    25.  
    26. memcpy(&readingStrs, &(infoVar->oAndS_str), readingLength);
    27.  
    28. //unlock the file to allow access
    29. lock.l_type = F_UNLCK;
    30. fcntl (fd, F_SETLKW, &lock);
    31.  
    32. char tOT[tOTL+1]; memcpy(tOT,readingStrs,tOTL); tOT[tOTL]='\0';
    33. char tON[tONL+1]; memcpy(tON,(readingStrs+tOTL),tONL); tON[tONL]='\0';
    34. char tSN[tSNL+1]; memcpy(tSN,(readingStrs+tOTL+tONL),tSNL); tSN[tSNL]='\0';
    35. char tSL[tSLL+1]; memcpy(tSL,(readingStrs+tOTL+tONL+tSNL),tSLL); tSL[tSLL]='\0';
    36. char tID[tIDL+1]; memcpy(tID,(readingStrs+tOTL+tONL+tSNL+tSLL),tIDL); tID[tIDL]='\0';
    37. char tMD[tMDL+1]; memcpy(tMD,(readingStrs+tOTL+tONL+tSNL+tSLL+tIDL),tMDL); tMD[tMDL]='\0';
    38.  
    39. operatorTel = loc->toUnicode(tOT);
    40. operatorName = loc->toUnicode(tON);
    41. stationNum = loc->toUnicode(tSN);
    42. stationLoc = loc->toUnicode(tSL);
    43. installationDate = loc->toUnicode(tID);
    44. maintenanceDate = loc->toUnicode(tMD);
    45.  
    46. //do smth now
    47. }
    To copy to clipboard, switch view to plain text mode 

    am i using QTextCodec correctly?

    now for saving to File :

    Qt Code:
    1. void monitorForm::writeToGuiFile()
    2. {
    3. QCString buffer=loc->fromUnicode(stationNum)+"\nEOV\n"+loc->fromUnicode(stationLoc)+"\nEOV\n"+
    4. loc->fromUnicode(operatorName)+"\nEOV\n"+loc->fromUnicode(operatorTel)+"\nEOV\n"+
    5. loc->fromUnicode(installationDate)+"\nEOV\n"+loc->fromUnicode(maintenanceDate)+"\nEOV\n";
    6. QFile file(guiFileName);
    7. if ( file.open( IO_WriteOnly ) )
    8. {
    9. QTextStream stream( &file );
    10. stream<<buffer;
    11. }
    12. file.close();
    13. }
    To copy to clipboard, switch view to plain text mode 

    if say QString operatorName is in greek, and i check the text file after the operation, i observe ??? instead of the text. So if i manually erase the ??? and put a greek word back in, and i read the file from my code, the data is shown correctly in the QLabels.
    here is the reading QFile function

    Qt Code:
    1. int monitorForm::readFromGuiFile()
    2. {
    3. QFile file(guiFileName);
    4. QCString lines[6]="";
    5. QCString curLine="";
    6. QCString sumLine="";
    7. int i=0;
    8. if ( file.open( IO_ReadOnly ) )
    9. {
    10. QTextStream stream( &file );
    11. while (!stream.atEnd())
    12. {
    13. curLine=stream.readLine();
    14. if ((curLine!="EOV"))
    15. {
    16. if (curLine!="")
    17. sumLine=sumLine+curLine+"\n";
    18. }
    19. else
    20. {
    21. lines[i]=sumLine;
    22. sumLine="";
    23. i++;
    24. }
    25. }//while
    26. file.close();
    27.  
    28. //remove the last char which is always \n due to the way
    29. //the file open parser (just above) works
    30. lines[0].remove( (lines[0].length()-1) ,1);
    31. lines[1].remove( (lines[1].length()-1) ,1);
    32. lines[2].remove( (lines[2].length()-1) ,1);
    33. lines[3].remove( (lines[3].length()-1) ,1);
    34. lines[4].remove( (lines[4].length()-1) ,1);
    35. lines[5].remove( (lines[5].length()-1) ,1);
    36.  
    37. stationNum=loc->toUnicode(lines[0]);
    38. stationLoc=loc->toUnicode(lines[1]);
    39. operatorName=loc->toUnicode(lines[2]);
    40. operatorTel=loc->toUnicode(lines[3]);
    41. installationDate=loc->toUnicode(lines[4]);
    42. maintenanceDate=loc->toUnicode(lines[5]);
    43.  
    44. return (0);
    45. }
    46. else
    47. return (1);
    48.  
    49. }
    To copy to clipboard, switch view to plain text mode 

    i have written it like this since the variable stationLoc might contain \n character since it stores an address. so i needed separator entries (EOV= end of variable).

    so any ideas what might be wrong with saving?
    Last edited by jacek; 15th November 2006 at 20:39. Reason: wrapped too long line

  5. #5
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    28
    Thanked 976 Times in 912 Posts

    Default Re: unable to save QCStrings properly in a buffer

    Quote Originally Posted by nass View Post
    am i using QTextCodec correctly?
    Yes, but instead of "loc->setCodecForCStrings(loc);" write "QTextCodec::setCodecForCStrings(loc);" as this is a static method.

    Maybe you should try this way:
    Qt Code:
    1. void monitorForm::writeToGuiFile()
    2. {
    3. QString eov( "\nEOV\n" );
    4. QFile file(guiFileName);
    5. if ( file.open( IO_WriteOnly ) )
    6. {
    7. QTextStream stream( &file );
    8. stream.setCodec( loc );
    9. stream << stationLoc << eov
    10. << stationLoc << eov
    11. << operatorName << eov
    12. << operatorTel ...;
    13. }
    14. file.close();
    15. }
    To copy to clipboard, switch view to plain text mode 

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.