home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Exec 3 / CD_Magazyn_EXEC_nr_3.iso / Recent / misc / edu / WhirlDisc.lha / WhirlDisc / Source / paedia.c < prev    next >
C/C++ Source or Header  |  2000-08-15  |  11KB  |  433 lines

  1. /*
  2.  
  3. File: paedia.c
  4. Author: Neil Cafferkey
  5. Copyright (C) 2000 Neil Cafferkey
  6.  
  7. This program is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU General Public License
  9. as published by the Free Software Foundation; either version 2
  10. of the License, or (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  20. MA 02111-1307, USA.
  21.  
  22. */
  23.  
  24. #include "viewer.h"
  25. #include <exec/memory.h>
  26. #include <dos/dos.h>
  27. #include <dos/dostags.h>
  28. #include <stdio.h>
  29. #include <string.h>
  30.  
  31. #include "paedia_protos.h"
  32. #include "general_protos.h"
  33. #include "deflated_sequence_protos.h"
  34. #include "article_protos.h"
  35. #include "index_protos.h"
  36. #include <proto/exec.h>
  37. #include <proto/dos.h>
  38.  
  39.  
  40. #define BLOCK_SIZE 512
  41. #define MAX_LINK_FILE_NAME_LENGTH 20
  42.  
  43. const TEXT main_file_name[]="info_dat/wb.dat";
  44. /*const TEXT link_file_name[]="links";*/
  45. const TEXT master_file_name[]="info_dat/master.ndx";
  46. const TEXT index_file_name[]="info_dat/ssubject.ndx";
  47. const TEXT orig_link_file_name[]="info_dat/rom_link.dat";
  48.  
  49.  
  50. static VOID GetBlocks(BPTR file,ULONG start_block,ULONG block_count,
  51.    UBYTE *buffer);
  52. static MediaLink GetPaediaLink(Paedia paedia,ULONG link_no);
  53.  
  54.  
  55.  
  56. /* Function: ConvertLinkFile
  57.  * =========================
  58.  * Converts the original link file into a new file with a non-textual
  59.  * format.
  60.  */
  61.  
  62. BOOL ConvertLinkFile(TEXT *old_file_name,TEXT *new_file_name)
  63. {
  64.    FILE *old_file;
  65.    ULONG line_count=0,i;
  66.    char ch;
  67.    MediaLink media_links,p;
  68.    BPTR new_file;
  69.    BOOL success=TRUE;
  70.  
  71.    /* Convert "rom link" text file into an array in memory */
  72.  
  73.    if(old_file=fopen(old_file_name,"rb"))
  74.    {
  75.  
  76.       /* Count the lines in the text file and allocate enough memory to
  77.        * hold its converted  contents. */
  78.  
  79.       for(ch=0;!feof(old_file);ch=getc(old_file))
  80.          if(ch=='\n')
  81.             line_count++;
  82.  
  83.       line_count;
  84.  
  85.       media_links=(MediaLink)AllocMem(sizeof(MediaLink_imp)
  86.          *line_count,MEMF_CLEAR);
  87.  
  88.       /* Fill array of media links */
  89.  
  90.       if(media_links)
  91.       {
  92.          rewind(old_file);
  93.          p=media_links;
  94.          for(i=0;i<line_count;i++)
  95.          {
  96.             fscanf(old_file,"%lu|%*[^|]|%*[^|]|%*[^|]|%*[^|]|%lu|%hu",
  97.                &(p->link_no),&(p->start_block),&(p->block_count));
  98.             getc(old_file);
  99.             p++;
  100.          }
  101.  
  102.          /* Write converted links into a new file */
  103.  
  104.          if(new_file=Open(new_file_name,MODE_NEWFILE))
  105.          {
  106.             if(Write(new_file,media_links,line_count
  107.                *sizeof(MediaLink_imp))==-1)
  108.                success=FALSE;
  109.             Close(new_file);
  110.          }
  111.  
  112.          FreeMem(media_links,sizeof(MediaLink_imp)*line_count);
  113.       }
  114.  
  115.       fclose(old_file);
  116.    }
  117.    else
  118.    {
  119.    success=FALSE;
  120.    }
  121.  
  122.    return success;
  123. }
  124.  
  125.  
  126.  
  127. /* Function: CreatePaedia
  128.  * ======================
  129.  * Creates a Paedia.
  130.  */
  131.  
  132. Paedia CreatePaedia(TEXT *data_dir_name,TEXT *paedia_dir_name)
  133. {
  134.    Paedia paedia;
  135.    ULONG line_count=0;
  136.    TEXT *path_name,*index_path_name,*link_file_name,*orig_link_path;
  137.    struct FileInfoBlock *temp_fib;
  138.    BPTR link_file=NULL,master_file=NULL;
  139.    BOOL success=TRUE;
  140.  
  141.    if(paedia=AllocMem(sizeof(Paedia_imp),MEMF_CLEAR))
  142.    {
  143.  
  144.       /* Construct the full path name for main file */
  145.  
  146.       if(path_name=AllocVec(strlen(paedia_dir_name)+
  147.          strlen(main_file_name)+2,0))
  148.       {
  149.  
  150.          strcpy(path_name,paedia_dir_name);
  151.  
  152.          AddPart(path_name,main_file_name,strlen(paedia_dir_name)+strlen(
  153.             main_file_name)+2);
  154.  
  155.          /* Open the main file and free its path name buffer */
  156.  
  157.          if(!(paedia->main_file=Open(path_name,MODE_OLDFILE)))
  158.          {
  159.             ReportError(NULL,ERROR_REPORT_FILE,path_name,0);
  160.             success=FALSE;
  161.          }
  162.          FreeVec(path_name);
  163.       }
  164.       else
  165.       {
  166.          ReportError(NULL,ERROR_REPORT_MEM,NULL,0);
  167.          success=FALSE;
  168.       }
  169.  
  170.       /* Make a string specifying the main file size */
  171.  
  172.       if(success)
  173.       {
  174.          if((temp_fib=AllocDosObjectTags(DOS_FIB,TAG_END))&&
  175.             (link_file_name=AllocVec(MAX_LINK_FILE_NAME_LENGTH+1,
  176.             MEMF_PUBLIC)))
  177.          {
  178.             ExamineFH(paedia->main_file,temp_fib);
  179.             sprintf(link_file_name,"%ld",temp_fib->fib_Size);
  180.             FreeDosObject(DOS_FIB,temp_fib);
  181.          }
  182.          else
  183.          {
  184.             ReportError(NULL,ERROR_REPORT_MEM,NULL,0);
  185.             success=FALSE;
  186.          }
  187.  
  188.          /* Construct the full path name for link file */
  189.  
  190.          if(success)
  191.          {
  192.             if(success&&(path_name=AllocVec(strlen(data_dir_name)+
  193.                strlen(link_file_name)+2,0)))
  194.             {
  195.                strcpy(path_name,data_dir_name);
  196.  
  197.                AddPart(path_name,link_file_name,strlen(data_dir_name)+
  198.                   strlen(link_file_name)+2);
  199.  
  200.                /* Open the link file and free its path name buffer */
  201.  
  202.                if(!(link_file=Open(path_name,MODE_OLDFILE)))
  203.                {
  204.  
  205.                   /* Create a new link file from the original textual link
  206.                    * file */
  207.  
  208.                   if(orig_link_path=AllocVec(strlen(paedia_dir_name)+
  209.                      strlen(orig_link_file_name)+2,0))
  210.                   {
  211.  
  212.                      /* TODO: should let user know what's happening */
  213.  
  214.                      strcpy(orig_link_path,paedia_dir_name);
  215.                      AddPart(orig_link_path,orig_link_file_name,
  216.                         strlen(paedia_dir_name)+strlen(orig_link_file_name)
  217.                         +2);
  218.                      ConvertLinkFile(orig_link_path,path_name);
  219.                   }
  220.                   else
  221.                   {
  222.                      ReportError(NULL,ERROR_REPORT_MEM,NULL,0);
  223.                      success=FALSE;
  224.                   }
  225.  
  226.                   /* Retry to open the apropriate link file */
  227.  
  228.                   if(!(link_file=Open(path_name,MODE_OLDFILE)))
  229.                   {
  230.                      ReportError(NULL,ERROR_REPORT_FILE,path_name,0);
  231.                      success=FALSE;
  232.                   }
  233.                }
  234.  
  235.                FreeVec(path_name);
  236.             }
  237.             else
  238.             {
  239.                ReportError(NULL,ERROR_REPORT_MEM,NULL,0);
  240.                success=FALSE;
  241.             }
  242.          }
  243.          FreeVec(link_file_name);
  244.       }
  245.  
  246.       /* Copy link file into memory */
  247.  
  248.       if(link_file)
  249.       {
  250.  
  251.          if(temp_fib=AllocDosObjectTags(DOS_FIB,TAG_END))
  252.          {
  253.             /* Get link file size */
  254.  
  255.             ExamineFH(link_file,temp_fib);
  256.             paedia->link_count=temp_fib->fib_Size/sizeof(MediaLink_imp);
  257.             FreeDosObject(DOS_FIB,temp_fib);
  258.  
  259.             /* Allocate memory for link data */
  260.  
  261.             paedia->media_links=AllocMem(sizeof(MediaLink_imp)
  262.                *paedia->link_count,MEMF_CLEAR);
  263.  
  264.             /* Read link data into memory */
  265.  
  266.             if(paedia->media_links)
  267.                Read(link_file,paedia->media_links,paedia->link_count
  268.                   *sizeof(MediaLink_imp));
  269.             else
  270.             {
  271.                ReportError(NULL,ERROR_REPORT_MEM,NULL,0);
  272.                success=FALSE;
  273.             }
  274.  
  275.          }
  276.          else
  277.          {
  278.             ReportError(NULL,ERROR_REPORT_MEM,NULL,0);
  279.             success=FALSE;
  280.          }
  281.  
  282.          Close(link_file);
  283.       }
  284.  
  285.       /* Construct the full path names for the index files */
  286.  
  287.       path_name=AllocVec(strlen(paedia_dir_name)+
  288.          strlen(master_file_name)+2,0);
  289.  
  290.       index_path_name=AllocVec(strlen(paedia_dir_name)+
  291.          strlen(index_file_name)+2,0);
  292.  
  293.       if(path_name&&index_path_name)
  294.       {
  295.          strcpy(path_name,paedia_dir_name);
  296.          strcpy(index_path_name,paedia_dir_name);
  297.  
  298.          AddPart(path_name,master_file_name,strlen(paedia_dir_name)+strlen(
  299.             master_file_name)+2);
  300.          AddPart(index_path_name,index_file_name,strlen(paedia_dir_name)+
  301.             strlen(index_file_name)+2);
  302.  
  303.          paedia->index=CreateIndex(path_name,index_path_name);
  304.          if(!paedia->index)
  305.             success=FALSE;
  306.  
  307.          FreeVec(path_name);
  308.          FreeVec(index_path_name);
  309.       }
  310.       else
  311.       {
  312.          ReportError(NULL,ERROR_REPORT_MEM,NULL,0);
  313.          success=FALSE;
  314.       }
  315.  
  316.       if(!success)
  317.       {
  318.          KillPaedia(paedia);
  319.          paedia=NULL;
  320.       }
  321.  
  322.    }
  323.    else
  324.    {
  325.       ReportError(NULL,ERROR_REPORT_MEM,NULL,0);
  326.    }
  327.  
  328.    return paedia;
  329. }
  330.  
  331.  
  332.  
  333. /* Function: GetPaediaItem
  334.  * =======================
  335.  * Extracts an article,picture etc. from a Paedia.
  336.  */
  337.  
  338. Sequence GetPaediaItem(Paedia paedia,ULONG link_no)
  339. {
  340.    MediaLink link=GetPaediaLink(paedia,link_no);
  341.    Sequence inflated=NULL;
  342.    DeflatedSequence deflated;
  343.    UBYTE *compressed_buffer;
  344.  
  345.    compressed_buffer=AllocMem(link->block_count*BLOCK_SIZE,MEMF_ANY);
  346.  
  347.    if(compressed_buffer)
  348.    {
  349.       GetBlocks(paedia->main_file,link->start_block,link->block_count,
  350.          compressed_buffer);
  351.  
  352.       deflated=CreateSequence(link->block_count*BLOCK_SIZE,
  353.          compressed_buffer);
  354.       if(deflated)
  355.       {
  356.          inflated=InflateSequence(deflated);
  357.          KillSequence(deflated);
  358.       }
  359.       FreeMem(compressed_buffer,link->block_count*BLOCK_SIZE);
  360.    }
  361.  
  362. #ifdef TEST
  363.    BPTR extract_file;
  364.  
  365.       if(extract_file=Open("T:extract",MODE_NEWFILE))
  366.       {
  367.          Write(extract_file,inflated->data,inflated->length);
  368.          Close(extract_file);
  369.       }
  370. #endif
  371.  
  372.    return inflated;
  373. }
  374.  
  375.  
  376.  
  377. /* Function: KillPaedia
  378.  * ====================
  379.  * Destroys a Paedia.
  380.  */
  381.  
  382. VOID KillPaedia(Paedia paedia)
  383. {
  384.  
  385.    if(paedia->index)
  386.       KillIndex(paedia->index);
  387.  
  388.    if(paedia->main_file)
  389.       Close(paedia->main_file);
  390.  
  391.    if(paedia->media_links)
  392.       FreeMem(paedia->media_links,paedia->link_count*sizeof(MediaLink_imp));
  393.  
  394.    FreeMem(paedia,sizeof(Paedia_imp));
  395.  
  396.    return;
  397. }
  398.  
  399.  
  400.  
  401. /* Function: GetPaediaLink
  402.  * =======================
  403.  * Finds a specific link in a paedia's link array.
  404.  */
  405.  
  406. static MediaLink GetPaediaLink(Paedia paedia,ULONG link_no)
  407. {
  408.    MediaLink p;
  409.  
  410.    for(p=paedia->media_links;p->link_no!=link_no;p++);
  411.  
  412.    return p;
  413. }
  414.  
  415.  
  416.  
  417. /* Function: GetBlocks
  418.  * ===================
  419.  * Reads data blocks from the main paedia file.
  420.  */
  421.  
  422. static VOID GetBlocks(BPTR file,ULONG start_block,ULONG block_count,
  423.    UBYTE *buffer)
  424. {
  425.    Seek(file,start_block*BLOCK_SIZE,OFFSET_BEGINNING);
  426.    Read(file,buffer,block_count*BLOCK_SIZE);
  427.  
  428.    return;
  429. }
  430.  
  431.  
  432.  
  433.