Solved

Saving text from 4 fields to a file

Posted on 1999-01-29
7
228 Views
Last Modified: 2013-12-26
I wrote a small programm where the user inputs some text inside 4 different fields.
How can I save this data to a file in way that it may be reopened and displayed inside the 4 fields? I mean in the same order in which it was inputted.
I'm using this struct for the four text fields:
typedef struct
{      
      TEHandle      inputFieldAuthorHdl;
      TEHandle      inputFieldTitleHdl;
      TEHandle      inputFieldPublisherHdl;
      TEHandle      inputFieldYearHdl;
      
} DocRec, **DocRecHandle;

Actually I'm able to save it, but when I reopen it, all the text appears in the first field. Even if I open it from Simple Text, the text appears like a continuos line.
0
Comment
Question by:supersax
  • 4
  • 3
7 Comments
 
LVL 3

Accepted Solution

by:
boonstra earned 50 total points
ID: 1291782
You haven't said how you input the data, but since you are able to write it to a file, you must be able to extract it properly.  It seems that your problem is that you cannot separate the individual field values once you have written them.

I'd suggest writing four 4-byte values at the start of the file, the GetHandleSize() values for each of your four TEHandles.  Then write GetHandleSize(teH) bytes of text for each of the four teH TEHandles.

When reading the file, first read len1,len2,len3, and len4, the four 4-byte length values.  Then read len1 characters into the first field, then len2 into the second field, etc.
0
 

Author Comment

by:supersax
ID: 1291783
Ok boonstra, what you say makes sense. But, since I do not have a lot of experience, I need to see a sample of code that does that. Eventually if you can show me the code at least for two field inputs. (Anyway, I'm able to extract the text properly with StringToExtended and ExtendedToString).
0
 
LVL 3

Expert Comment

by:boonstra
ID: 1291784
This code demonstrates how the proposed solution works.  

static void Initialize(void)
{
      InitGraf(&qd.thePort);
      InitFonts();
      InitWindows();
      InitMenus();
      TEInit();
      InitDialogs(nil);
      InitCursor();

}

static void WriteTEH(TEHandle teH,long lng, FILE *outFile)
{
      unsigned char state;
      state = HGetState((**teH).hText);
      HLock((**teH).hText);
      fwrite(*(**teH).hText,sizeof(char),lng,outFile);
      HSetState((**teH).hText,state);
}

static void ReadTEH(TEHandle teH,long lng, FILE *inFile)
{
      unsigned char state;
      state = HGetState((**teH).hText);
      HLock((**teH).hText);
      fread(*(**teH).hText,sizeof(char),lng,inFile);
      HSetState((**teH).hText,state);
}

int main(void)
{
      TEHandle te1,te2;
      Rect destRect,viewRect;
      long size1,size2;
      FILE *outFile,*inFile;
      char text1[] = "this is text 1";
      char text2[] = "this is text 2 but it is longer";
      
      Initialize();
      
      SetRect(&destRect,0,0,100,100);
      SetRect(&viewRect,0,0,100,100);
      
/* initialize - this is replaced with whatever code you use to get your TEHandles */
      te1 = TENew(&destRect,&viewRect);
      te2 = TENew(&destRect,&viewRect);
      TEInsert(text1,strlen(text1),te1);
      TEInsert(text2,strlen(text2),te2);
      
/* write file */
      outFile = fopen("test.out","w");
      if (0==outFile) DebugStr("\p unable to open output file");
      
      size1 = GetHandleSize((**te1).hText);
      size2 = GetHandleSize((**te2).hText);
      
      fwrite(&size1,sizeof(long),1,outFile);
      fwrite(&size2,sizeof(long),2,outFile);
      
      WriteTEH(te1,size1,outFile);
      WriteTEH(te2,size2,outFile);
      
      fclose(outFile);
      
/* clear a byte of the text so we can see it is read properly */
      **(**te1).hText = 0;
      **(**te2).hText = 0;
      size1 = size2 = 0;

/* read file */
      inFile = fopen("test.out","r");
      if (0==inFile) DebugStr("\p unable to open input file");
      
      fread(&size1,sizeof(long),1,inFile);
      fread(&size2,sizeof(long),2,inFile);
      
      ReadTEH(te1,size1,inFile);
      ReadTEH(te2,size2,inFile);
      
      
}


0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 

Author Comment

by:supersax
ID: 1291785
Saving seems working. May be I have to convert the TEHandles to strings before saving.
I try also to use the following code. I can't make it work well to read the file. Also, how do you display the content to the file from the TEHandle back to editable text?

// ???????????????????????? doSaveAsFile
void  doSaveAsFile(TEHandle fieldOneHdl, TEHandle fieldTwoHdl)
{
      StandardFileReply      fileReply;
      WindowPtr                              windowPtr;
      SInt16                                    fileRefNum;
      SInt32                                    fieldOneLength, fieldTwoLength;
      DocRecHandle            docRecHdl;

      StandardPutFile("\pSave as:","\pUntitled",&fileReply);
      if(fileReply.sfGood)
      {
            windowPtr = FrontWindow();
            SetWTitle(windowPtr,fileReply.sfFile.name);

            if(!(fileReply.sfReplacing))
                  FSpCreate(&fileReply.sfFile,'????','TEXT',fileReply.sfScript);

            FSpOpenDF(&fileReply.sfFile,fsCurPerm,&fileRefNum);

            fieldOneLength = (*(*docRecHdl)->inputFieldOneHdl)->teLength;
            fieldTwoLength = (*(*docRecHdl)->inputFieldTwoHdl)->teLength;
            
            fieldOneHdl = (*docRecHdl)->inputFieldOneHdl;
            fieldTwoHdl = (*docRecHdl)->inputFieldTwoHdl;            
            
            FSWrite(fileRefNum,&fieldOneLength,*fieldOneHdl);
            FSWrite(fileRefNum,&fieldTwoLength,*fieldTwoHdl);
            
            FSClose(fileRefNum);
      }
}

???????????? doOpenCommand

void  doOpenCommand(void)
{
      StandardFileReply      fileReply;
      SFTypeList                        fileTypes;      

      fileTypes[0] = 'TEXT';

      StandardGetFile(NULL,1,fileTypes,&fileReply);
      if(fileReply.sfGood)
            doOpenFile(fileReply.sfFile);
}

// ?????????? doOpenFile

void  doOpenFile(FSSpec fileSpec)
{
      WindowPtr             windowPtr;
      DocRecHandle      docRecHdl;
      TEHandle                  fieldOneHdl, fieldTwoHdl;
      SInt16                        fileRefNum;
      SInt32                        fieldOneLength, fieldTwoLength; //textLength
      Handle                        textBuffer1,textBuffer2;

      if((windowPtr = doNewDocWindow()) == NULL)
            return;

      docRecHdl = (DocRecHandle) (GetWRefCon(windowPtr));;
 fieldOneHdl = (*docRecHdl)->inputFieldOneHdl;
      fieldTwoHdl = (*docRecHdl)->inputFieldTwoHdl;

      SetWTitle(windowPtr,fileSpec.name);
      
      FSpOpenDF(&fileSpec, fsCurPerm, &fileRefNum);

      SetFPos(fileRefNum,fsFromStart,0);
      GetEOF(fileRefNum,&fieldOneLength);
      GetEOF(fileRefNum,&fieldTwoLength);

      if(fieldOneLength > 32767 )
            fieldOneLength = 32767;

      textBuffer1 = NewHandle((Size) fieldOneLength);
      textBuffer2 = NewHandle((Size) fieldTwoLength);

      FSRead(fileRefNum,&fieldOneLength,*textBuffer1);
      FSRead(fileRefNum,&fieldTwoLength,*textBuffer2);

      MoveHHi(textBuffer1);      MoveHHi(textBuffer2);
      HLock(textBuffer1);      HLock(textBuffer2);

      TESetText(*textBuffer1, fieldOneLength, fieldOneHdl);
      TESetText(*textBuffer2, fieldTwoLength, fieldTwoHdl);

      HUnlock(textBuffer1);      HUnlock(textBuffer2);
      DisposeHandle(textBuffer1);      DisposeHandle(textBuffer2);

      FSClose(fileRefNum);

      (*fieldOneHdl)->selStart = 0;      (*fieldTwoHdl)->selStart = 0;
      (*fieldOneHdl)->selEnd = 0;      (*fieldTwoHdl)->selEnd = 0;

      ShowWindow(windowPtr);
}
0
 
LVL 3

Expert Comment

by:boonstra
ID: 1291786
Your read code doesn't work because you don't appear to be writing the text field lengths to the file.  You need to include something like this before you write the strings:
  bytesToWrite = sizeof(SInt32)
  FSWrite(fileRefNum,&bytesToWrite,&fieldOneLength);

Then you need to read the length back:
  bytesToRead = sizeof(SInt32)
  FSRead(fileRefNum,&bytesToRead,&fieldOneLength);

Then you can read the text:
  bytesToRead = fieldOneLength;
  FSRead(fileRefNum,&bytesToRead,*textBuffer1);

To put the text read from the file back into your TEHandle, use TESetText (as you are doing):

TESetText(*textBuffer1,fieldOneLength,fieldOneHdl);
0
 

Author Comment

by:supersax
ID: 1291787
Thank you boonstra. Now it works, but when it reads back the text, the text does not appear right (it appears &a!/´é'@%^*). Also, there is a lot of stuff inside each field.
Here is the code again, which I revised including arrays:

// ................................................ doSaveAsFile
void      doSaveAsFile(void)
{
      StandardFileReply fileReply;
      WindowPtr windowPtr;
      SInt16 fileRefNum;
      SInt32 fieldLength[100];
      DocRecHandle docRecHdl;
      TEHandle fieldHdl[100];
      
      int i=0, j=0,m=0, n=0;
      
      SInt32 bytesToWrite;
            
      bytesToWrite = sizeof(SInt32); // boonstra suggestion

      StandardPutFile("\pSave as:","\puntitled",&fileReply);
      if(fileReply.sfGood)
      {
            windowPtr = FrontWindow();
            SetWTitle(windowPtr,fileReply.sfFile.name);

            if(!(fileReply.sfReplacing))
            FSpCreate(&fileReply.sfFile,'????','TEXT',fileReply.sfScript);

            FSpOpenDF(&fileReply.sfFile,fsCurPerm,&fileRefNum);

            for(i=0; i<gMaxFields; i++)
            {
                  fieldLength[i] =   (*(*docRecHdl)->inputHdl[i])->teLength;
                  fieldHdl[i] =   (*docRecHdl)->inputHdl[i];
            }
            
            for(j=0; j<gMaxFields; j++)
            {
                  FSWrite(fileRefNum,&bytesToWrite,&fieldLength[j]); // boonstra suggestion
            }

            for(m=0; m<gMaxFields; m++)
            {
                  FSWrite(fileRefNum,&fieldLength[m],*fieldHdl[m]);
            }

            FSClose(fileRefNum);
      }
}

// ................................................ doOpenCommand

void      doOpenCommand(void)
{
      StandardFileReply fileReply;
      SFTypeList fileTypes;

      fileTypes[0] = 'TEXT';

      StandardGetFile(NULL,1,fileTypes,&fileReply);
      if(fileReply.sfGood)
      doOpenFile(fileReply.sfFile);
}

// ................................................ doOpenFile

void      doOpenFile(FSSpec fileSpec)
{
      WindowPtr windowPtr;
      SInt16 fileRefNum;
      SInt32 fieldLength[100]; //textLength
      DocRecHandle docRecHdl;
      TEHandle fieldHdl[100];
      int i=0, j=0, m=0, n=0, p=0, r=0, s=0, t=0, v=0;
      
      Handle textBuffer[100];
      SInt32 bytesToRead;
                  
      bytesToRead = sizeof(SInt32); // boonstra suggestion
      
      openWindow();

      docRecHdl = (DocRecHandle) (GetWRefCon(gWindowPtr));
      
      for(i=0; i<gMaxFields;i++)
      {
            fieldHdl[i] = (*docRecHdl)->inputHdl[i];
      }

      SetWTitle(gWindowPtr,fileSpec.name);

      FSpOpenDF(&fileSpec, fsCurPerm, &fileRefNum);

      SetFPos(fileRefNum,fsFromStart,0);
      
      for(j=0; j<gMaxFields; j++)
      {
            GetEOF(fileRefNum,&fieldLength[j]);
      }

      for(m=0; m<gMaxFields; m++)
      {
            if(fieldLength[m] > 32767 )
            fieldLength[m] = 32767;
      }
      

      for(n=0; n<gMaxFields; n++)
      {
            textBuffer[n] = NewHandle((Size) fieldLength[n]);
      }
      
      for(p=0; p<gMaxFields; p++)
      {
            FSRead(fileRefNum,&bytesToRead,&fieldLength[p]); // read the length back
      }
      
      for(r=0; r<gMaxFields; r++)
      {
            bytesToRead = fieldLength[r];
            FSRead(fileRefNum,&bytesToRead,*textBuffer[r]); //read the text
      }

      for(s=0; s<gMaxFields; s++)
      {
            MoveHHi(textBuffer[s]);
            HLock(textBuffer[s]);
      }

       for( t=0; t<gMaxFields; t++)
      {
            TESetText(*textBuffer[t], fieldLength[t], fieldHdl[t]); // put the text read from the file back into your TEHandle
      }
      
      for(v=0; v<gMaxFields; v++)
      {
            HUnlock(textBuffer[v]);
            DisposeHandle(textBuffer[v]);
      }
      FSClose(fileRefNum);
      
      (*fieldHdl[0])->selStart = 0;
      (*fieldHdl[0])->selEnd = 0;

      ShowWindow(gWindowPtr);
}

0
 
LVL 3

Expert Comment

by:boonstra
ID: 1291788
You need to write out of the hText field of fieldHdl, i.e., replace

FSWrite(fileRefNum,&fieldLength[m],(*fieldHdl[m]); //bad

with

FSWrite(fileRefNum,&fieldLength[m],*(**fieldHdl[m]).hText);

Also, you should set bytesToRead to sizeof(SInt32) inside of the fieldLength read loop, as it is overwritten with each FSRead.  Same with the fieldLength write loop, although it will only matter if there is a problem with the write.

I'd also recommend an HGetState, HLock, FSWrite, HSetState around the text write code to prevent memory from moving during the FSWrite.
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

Suggested Solutions

Introduction: Ownerdraw of the grid button.  A singleton class implentation and usage. Continuing from the fifth article about sudoku.   Open the project in visual studio. Go to the class view – CGridButton should be visible as a class.  R…
If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now