Results 1 to 14 of 14

Thread: unable to save QCStrings properly in a buffer

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

    Default unable to save QCStrings properly in a buffer

    hello everyone,
    i am having some bit of trouble while trying to save on a shared memory segment.. just a bufer really for all interest here. i get a segmentation fault when i try to save some QCStrings concatenated together using memcpy.. please have a look.


    Qt Code:
    1. void monitorForm::int()
    2. {
    3. stationNum="1234";
    4. stationLoc="hello";
    5. operatorName="hihi";
    6. operatorTel="12345678";
    7. installationDate="10/10/2000";
    8. maintenanceDate="22/22/2000";
    9. saveInfo(operatorTel,operatorName,stationNum,stationLoc,installationDate,maintenanceDate);
    10. }
    11.  
    12. /*.....*/
    13.  
    14. void monitorForm::saveInfo(QString tempOperTel, QString tempOperName, QString tempStatNum, QString tempStatLoc,
    15. QString tempInstallDate, QString tempMaintenDate)
    16. {
    17. //convert to ASCII
    18. QCString tOT = tempOperTel.local8Bit();
    19. QCString tON = tempOperName.local8Bit();
    20. QCString tSN = tempStatNum.local8Bit();
    21. QCString tSL = tempStatLoc.local8Bit();
    22. QCString tID = tempInstallDate.local8Bit();
    23. QCString tMD = tempMaintenDate.local8Bit();
    24.  
    25. int tOTL = tOT.length();
    26. int tONL = tON.length();
    27. int tSNL = tSN.length();
    28. int tSLL = tSL.length();
    29. int tIDL = tID.length();
    30. int tMDL = tMD.length();
    31.  
    32. const char *savingStrs=tOT+tON+tSN+tSL+tID+tMD;
    33. int savingLength = tOTL + tONL + tSNL + tSLL + tIDL + tMDL ;
    34.  
    35. printf("savingStrs = %s\n",savingStrs);
    36. printf("%d+%d+%d+%d+%d+%d = %d\n",tOTL , tONL , tSNL , tSLL , tIDL , tMDL , savingLength);
    37.  
    38. //lock the file for writing
    39. memset (&lock, 0, sizeof(lock));
    40. lock.l_type = F_WRLCK;
    41. fcntl (fd, F_SETLKW, &lock);
    42.  
    43. //file_memory is a pointer to the zero offset of the sh.mem. segment
    44. //opcode offset is just an offset in the sh.mem where we write some index values
    45. *((char*)file_memory+wOpcodeOffset) = 9;
    46. struct ShMem *infoVar=(ShMem*)((char*)file_memory);
    47.  
    48. infoVar->oTL = tOTL;
    49. infoVar->oNL = tONL;
    50. infoVar->sNL = tSNL;
    51. infoVar->sLL = tSLL;
    52. infoVar->iDL = tIDL;
    53. infoVar->mDL = tMDL;
    54. printf("hello\n");
    55. memcpy(infoVar->oAndS_str, savingStrs, savingLength);
    56. printf("hello2\n");
    57.  
    58. //unlock the file to allow access
    59. lock.l_type = F_UNLCK;
    60. fcntl (fd, F_SETLKW, &lock);
    61. }
    To copy to clipboard, switch view to plain text mode 

    the code crashes on memcpy(...). that is between printf("hello\n"); and printf("hello2\n");

    i have noticed something awkard. when i printf savingStrs i get exactly the following output:
    savingStrs =5678hihi1234hello10/10/200022/22/2000

    but the savingLength variable returns 41 which is correct and expected.

    (notice that the debugging output doesn't have a space " " after the equals sign "=". but especially notice that 4 first bytes of the variable tempOperTel has been trunsated) any ideas?
    thank you for your help
    nass
    Last edited by jacek; 13th November 2006 at 17:09. Reason: wrapped too long line

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

    Default Re: unable to save QCStrings properly in a buffer

    Quote Originally Posted by nass View Post
    const char *savingStrs=tOT+tON+tSN+tSL+tID+tMD;
    You create a temporary QCString object, obtain a pointer to its internal data and then that object gets destroyed.

    Try:
    Qt Code:
    1. QCString tmp = tOT+tON+tSN+tSL+tID+tMD;
    2. const char *savingStrs = tmp;
    3. int savingLength = tmp.length()
    To copy to clipboard, switch view to plain text mode 

    Are you sure that infoVar->oAndS_str is a correct pointer?

  3. #3
    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

    thank you for your help, we are halfway there.
    i did as you said and yes i do get the right output now.

    savingStrs = 12345678hihi1234hello10/10/200022/22/2000

    however i still get a seg. fault. after printf("hello\n");..

    i wonder if it could possibly not like the infoVar->oAndS_str pointer. it is defined as char * in the sh.mem. structure.

    what did you mean if itsthe correct pointer?

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

    Default Re: unable to save QCStrings properly in a buffer

    Quote Originally Posted by nass View Post
    what did you mean if itsthe correct pointer?
    For example "char *ptr = 0xdeafbeef" is most likely an invalid pointer.

  5. #5
    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 still don't see where is the fault... im sorry but im just about learning c++...
    here is the shared memory structure as defined so as to perhaps help identify if there is a fault

    look at the bottom for the defined members of shared structure that are accessed through the declaration infoVar (of type ShMem)

    Qt Code:
    1. //-------------------------------Shared Memory Structure------------------------ ----------
    2. struct SchedDateTime
    3. {
    4. int cTH;
    5. int cTMin;
    6. int cTD;
    7. int cTMon;
    8. int cTY;
    9. };
    10.  
    11. struct CSched
    12. {
    13. SchedDateTime On;
    14. SchedDateTime Off;
    15. };
    16.  
    17. struct ShMem
    18. {
    19. unsigned char opCode0;
    20. unsigned char opCode1;
    21. unsigned char opCode2;
    22. unsigned char opCode3;
    23.  
    24. float cPow;
    25. float cRPow;
    26. float cVolt;
    27. float cC1C;
    28. float cC2C;
    29. float cC3C;
    30. /*float curCapCurrent[3];*/
    31.  
    32. unsigned char cC1S;
    33. unsigned char cC2S;
    34. unsigned char cC3S;
    35. /*unsigned char curCapState[3];*/
    36.  
    37. int appDTOff;
    38.  
    39. /*unsigned char operationalState;*/
    40. unsigned char operState;
    41. unsigned char logSampPer;
    42. unsigned char logT;
    43. unsigned char chLog;
    44. //-----------------------------powerSensor
    45. unsigned char powerSR;
    46. int powerRes;
    47. int powerMinI;
    48. int powerMaxI;
    49. int powerF;
    50. float powerDCBO;
    51. //-----------------------------ReactiveSensor
    52. unsigned char rPowerSR;
    53. int rPowerRes;
    54. int rPowerMinI;
    55. int rPowerMaxI;
    56. int rPowerF;
    57. float rPowerDCBO;
    58. //-----------------------------VoltageSensor
    59. unsigned char voltageSR;
    60. int voltageRes;
    61. int voltageMinI;
    62. int voltageMaxI;
    63. int voltageF;
    64. float voltageDCBO;
    65. //-----------------------------IC1Sensor
    66. unsigned char cap1SR;
    67. int cap1Res;
    68. int cap1MinI;
    69. int cap1MaxI;
    70. int cap1F;
    71. float cap1DCBO;
    72. //-----------------------------IC2Sensor
    73. unsigned char cap2SR;
    74. int cap2Res;
    75. int cap2MinI;
    76. int cap2MaxI;
    77. int cap2F;
    78. float cap2DCBO;
    79. //-----------------------------IC3Sensor
    80. unsigned char cap3SR;
    81. int cap3Res;
    82. int cap3MinI;
    83. int cap3MaxI;
    84. int cap3F;
    85. float cap3DCBO;
    86. //-----------Auto Mode Config Parameters
    87. float aMon;
    88. float aMoff;
    89. float aKon;
    90. float aKoff;
    91. int aInTime;
    92. //-----------Manual Mode Config Parameters
    93. unsigned char mC1St;
    94. unsigned char mC2St;
    95. unsigned char mC3St;
    96. /*unsigned char MANUAL_capstate[3];*/
    97.  
    98.  
    99. //------------Timer Mode Config Parameters
    100. /*unsigned char TIMER_cap1_daily;
    101.   unsigned char TIMER_cap2_daily;
    102.   unsigned char TIMER_cap3_daily;*/
    103.  
    104. /*unsigned char Timer_cap1_daily[3];*/
    105. unsigned char c1TD;
    106. unsigned char c2TD;
    107. unsigned char c3TD;
    108. CSched c1Sched;
    109. CSched c2Sched;
    110. CSched c3Sched;
    111. /*GUISchedule cxTimerOnOff[3];*/
    112.  
    113. /*an alarm code*/
    114. unsigned char alarmCode;
    115.  
    116. /*autoCalibration signal*/
    117. unsigned char aCc; //the caller (1of6 sensors)
    118.  
    119. /*synch error correction flag*/
    120. unsigned char synchErr;
    121. unsigned char rPowErr;
    122.  
    123. /*station and operator infromation*/
    124. int oTL;
    125. int oNL;
    126. int sNL;
    127. int sLL;
    128. int iDL;
    129. int mDL;
    130. char *oAndS_str;
    131.  
    132. };
    To copy to clipboard, switch view to plain text mode 

    thank you for your help
    nass

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

    Default Re: unable to save QCStrings properly in a buffer

    Where does file_memory comes from? Does it have a correct value? How did you initialize the area that file_memory points to? What is the value of infoVar->oAndS_str? Are there any other programs that use that shared memory?

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

    file_memory is initialised using standard linux init descriptors.. nothing weird here..

    Qt Code:
    1. void initSharingMem()
    2. {
    3. /* Open the file. */
    4. fd = open (file, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
    5. if (fd==-1) printf("error in opening file");
    6. lseek (fd, FILE_LENGTH+1, SEEK_SET);
    7. write (fd, "", 1);
    8. lseek (fd, 0, SEEK_SET);
    9. /* Create the memory-mapping. */
    10. file_memory = mmap (0, FILE_LENGTH, PROT_READ | PROT_WRITE,MAP_SHARED, fd, 0);
    11. }
    To copy to clipboard, switch view to plain text mode 

    file_memory should be right since the saving of the integers is done properly, not to mention that the rest of the variables you see in the sh.mem header file, as saved and retried in a similar manner in other procedures. so i doubt file_memory pointer outputs a wrong value.
    it is something in the range 0x8000xxxx .. im not quite sure i can check tomorrow from my work.

    well infoVar->oAndS_str is a pointer it should point to the beginning of the characters that make up the string... or rather, the stream of char is moved from the 'head' to the location where infoVar->oAndS_str looks.

    no other programs use the shared memory yet, the other code is being developed currently.

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

    Default Re: unable to save QCStrings properly in a buffer

    Quote Originally Posted by nass View Post
    well infoVar->oAndS_str is a pointer it should point to the beginning of the characters that make up the string...
    If you can successfully access and change other fields of that structure, then I would double check where does infoVar->oAndS_str point.

    On the second thought, how do you expect it to work? That shared memory segment might be mapped into each process's address space in a different place, so each process should use a different pointer. Shouldn't you use a char array or some offset instead?

    Quote Originally Posted by nass View Post
    no other programs use the shared memory yet, the other code is being developed currently.
    OK, just don't forget that different compilers can align ShMem fields in a different way.

  9. #9
    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

    hm ok i found out the problem.
    i checked and infoVar->oAndS_str points to nil. that definitely is not right, but i have to ask why.. i mean it appears that a pointer inside a structure is not even given 8bits on structure declaration in the code ?????!, cause if it is, it should be able to be adressed

    So instead i declared oAndS_str as char, so that it can then use its reference (address). it does work correctly now
    Thankyou for your help.
    nass

  10. #10
    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.

  11. #11
    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?

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

    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 

  13. #13
    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

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

    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
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.