home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / uucp / auucp+-1.02 / fuucp_plus_src.lzh / uucplib / buffer / buffer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-05  |  11.5 KB  |  392 lines

  1. /* -------------------------------------------------------------------------------------- */
  2.  
  3. #include "exec/memory.h"
  4. #include "dos/dos.h"
  5. #include "dos/dosextens.h"
  6. #include "clib/exec_protos.h"
  7. #include "clib/dos_protos.h"
  8. #include "pragmas/exec_pragmas.h"
  9. #include "pragmas/dos_pragmas.h"
  10. #include <string.h>
  11. #include "buffer.h"
  12.  
  13. /* -------------------------------------------------------------------------------------- */
  14.  
  15. /*  lese_puffer - !PRIVATE ROUTINE!
  16.     Liest so viel wie m÷glich Byte in den Buffer ein. Grundannahme ist, da▀ der
  17.     Puffer "ausbenutzt" ist. Es wird sowohl die neue Ausnutzung des Puffers wie
  18.     auch der Zeiger auf die aktuelle Position korrigiert.
  19. */
  20.  
  21. extern struct ExecBase *SysBase;
  22. extern struct DOSBase  *DOSBase;
  23.  
  24. STATIC BOOL lese_puffer (struct datei *meine_datei)
  25. {
  26.   LONG anzahl;
  27.  
  28.   if (meine_datei->modus == MODE_OLDFILE)
  29.   {
  30.     anzahl = Read (meine_datei->datei_zeiger, meine_datei->puffer_zeiger, PUFFER_GROESSE);
  31.     if (anzahl == -1)
  32.     {
  33.       return (FALSE);
  34.     }
  35.     meine_datei->puffer_voelle = anzahl;
  36.     meine_datei->akt_position = 0;
  37.     return (TRUE);
  38.   }  
  39.   return (FALSE);
  40. }
  41.  
  42. /* -------------------------------------------------------------------------------------- */
  43.  
  44. /*  schreibe_puffer - !PRIVATE ROUTINE!
  45.     Schreib den Puffer bis "akt_position" in die Datei auf dem gewΣhlten Medium.
  46.     "akt_position" wird danach zurⁿckgesetzt, der Puffer kann neu benutzt werden.
  47.     Sollten keine Zeichen im Puffer sein (weil "akt_position" auf 0 steht), wird
  48.     "TRUE" zurⁿckgeliefert.
  49. */
  50.  
  51. STATIC BOOL schreibe_puffer (struct datei *meine_datei)
  52. {
  53.   LONG anzahl;
  54.  
  55.   if (meine_datei->modus == MODE_NEWFILE)
  56.   {
  57.     if (meine_datei->akt_position > 0)
  58.     {
  59.       anzahl = Write (meine_datei->datei_zeiger, meine_datei->puffer_zeiger, meine_datei->akt_position);
  60.       if (anzahl == -1)
  61.       {
  62.         return (FALSE);
  63.       }
  64.       if (anzahl != meine_datei->akt_position)
  65.       {
  66.         return (FALSE);
  67.       }
  68.       meine_datei->akt_position = 0;
  69.       return (TRUE);
  70.     }
  71.     else
  72.     {
  73.       return (TRUE);
  74.     }
  75.   }  
  76.   return (FALSE);
  77. }
  78.  
  79. /* -------------------------------------------------------------------------------------- */
  80.  
  81. /*  oeffne_datei
  82.     ╓ffnet Datei zum sequenziellen Lesen (Modus MODE_OLDFILE) oder legt neue
  83.     Datei zum sequenziellen Schreiben an (Modus MODE_NEWFILE). Rⁿckgabe ist
  84.     eine Struktur vom Typ "datei". Rⁿckgabe ist NULL wenn Datei nicht ge-
  85.     ÷ffnet werden kann oder kein RAM fⁿr Puffer da ist.
  86. */
  87.  
  88. struct datei * oeffne_datei (char *name, ULONG modus)
  89. {
  90.   struct datei *meine_datei;
  91.   char *mein_puffer;
  92.   BPTR mein_bptr;
  93.   BOOL ergebnis;
  94.  
  95.   meine_datei = AllocMem (sizeof (struct datei), MEMF_CLEAR|MEMF_PUBLIC);
  96.   if (meine_datei)
  97.   {
  98.     mein_puffer = AllocMem (PUFFER_GROESSE, MEMF_CLEAR);
  99.     if (mein_puffer)
  100.     {
  101.       if ((modus == MODE_OLDFILE) || (modus == MODE_NEWFILE))
  102.       {
  103.         mein_bptr = Open (name, modus);
  104.         if (mein_bptr)
  105.         {
  106.           meine_datei->datei_zeiger = mein_bptr;
  107.           meine_datei->puffer_zeiger = mein_puffer;
  108.           meine_datei->puffer_groesse = PUFFER_GROESSE;
  109.           meine_datei->akt_position = 0;
  110.           meine_datei->modus = modus;
  111.           if (modus == MODE_OLDFILE)
  112.           {
  113.             ergebnis = lese_puffer (meine_datei);
  114.             if (ergebnis == TRUE)
  115.             {
  116.               return (meine_datei);
  117.             }
  118.           }
  119.           else
  120.           {
  121.             meine_datei->puffer_voelle = 0;
  122.             return (meine_datei);
  123.           }
  124.           Close (mein_bptr);
  125.         }
  126.       }
  127.       FreeMem (mein_puffer, PUFFER_GROESSE);
  128.     }
  129.     FreeMem (meine_datei, sizeof (struct datei));
  130.   }
  131.   return (NULL);
  132. }
  133.  
  134. /* -------------------------------------------------------------------------------------- */
  135.  
  136. /*  hole_zeichen
  137.     Holt aus der Datei, welche in "*meine_datei" uebergeben wird die
  138.     gewⁿnschte Anzahl von Byte und kopiert diese in den "puffer". Benutzer mu▀
  139.     selbst dafⁿr sorgen da▀ der Puffer ausreichend gro▀ ist.
  140.     Als Rⁿckgabe gibts die Anzahl der gelesenen Byte oder einen Fehlercode:
  141.  
  142.     LESE_FEHLER                   : Datei konnte gelesen werden. Pufferung
  143.                                     defekt. Datei schlie▀en und neu ÷ffnen.
  144.     FALSCHER_MODUS                : Datei ist mit Modus "MODE_NEWFILE" ge-
  145.                                     ÷ffnet und kann nicht gelesen werden.
  146. */
  147.  
  148. LONG hole_zeichen (struct datei *meine_datei, char *puffer, ULONG anzahl)
  149. {
  150.   LONG zaehler = 0;
  151.   BOOL ergebnis;
  152.  
  153.   if (meine_datei->modus == MODE_OLDFILE)
  154.   {
  155.     if (meine_datei->akt_position > (meine_datei->puffer_groesse - 1))
  156.     {
  157.       ergebnis = lese_puffer (meine_datei);
  158.       if (ergebnis == FALSE)
  159.       {
  160.         return (LESE_FEHLER);
  161.       }
  162.     }
  163.     if (meine_datei->akt_position > (LONG) (meine_datei->puffer_voelle - 1))
  164.     {
  165.       return (0L);
  166.     }
  167.     while (anzahl > 0)
  168.     {
  169.       if (meine_datei->akt_position + anzahl > meine_datei->puffer_voelle)
  170.       {
  171.         memcpy (puffer + zaehler, meine_datei->puffer_zeiger + meine_datei->akt_position,
  172.                 meine_datei->puffer_voelle - meine_datei->akt_position);
  173.         zaehler += meine_datei->puffer_voelle - meine_datei->akt_position;
  174.         anzahl -= meine_datei->puffer_voelle - meine_datei->akt_position;
  175.         ergebnis = lese_puffer (meine_datei);
  176.         if (ergebnis == FALSE)
  177.         {
  178.           return (LESE_FEHLER);
  179.         }
  180.         if (meine_datei->puffer_voelle == 0)
  181.         {
  182.           return (zaehler);
  183.         }
  184.       }
  185.       else
  186.       {
  187.         memcpy (puffer + zaehler, meine_datei->puffer_zeiger + meine_datei->akt_position, anzahl);
  188.         meine_datei->akt_position += anzahl;
  189.         zaehler += anzahl;
  190.         return (zaehler);
  191.       }
  192.     }
  193.   }
  194.   else
  195.   {
  196.     return (FALSCHER_MODUS);
  197.   }
  198. }
  199.  
  200. /* -------------------------------------------------------------------------------------- */
  201.  
  202. /*  schliesse_datei
  203.     Schlie▀ die Datei (und schreibt vorher beim Schreibmodus den Puffer in
  204.     die Datei) und gibt allen allozierten Speicher wieder frei. Diese Routine
  205.     liefert einen der definierten Fehlercodes zurⁿck. Beim Fehler "NICHT_SCHLIESSBAR"
  206.     werden die Strukturen und der Puffer _*NICHT*_ freigegeben und einen
  207.     erneuten Schliessversuch m÷glich zu machen.
  208.  
  209.     NICHT_SCHLIESSBAR                 : Datei kann nicht geschlossen werden. Keine
  210.                                         ─nderung durchgefⁿhrt.
  211.     KEIN_FEHLER                       : Datei dicht und Puffer entfernt.
  212.     MEDIUM_VOLL                       : Medium ist voll oder Puffer konnte aus anderen
  213.                                         Grⁿnden nicht geschrieben werden.
  214. */
  215.  
  216. LONG schliesse_datei (struct datei *meine_datei)
  217. {
  218.   BOOL ergebnis;
  219.  
  220.   if (meine_datei->modus == MODE_OLDFILE)
  221.   {
  222.     ergebnis = Close (meine_datei->datei_zeiger);
  223.     if (ergebnis == FALSE)
  224.     {
  225.       return (NICHT_SCHLIESSBAR);
  226.     }      
  227.     FreeMem (meine_datei->puffer_zeiger, PUFFER_GROESSE);
  228.     FreeMem (meine_datei, sizeof (struct datei));
  229.     return (KEIN_FEHLER);
  230.   }
  231.   else
  232.   {
  233.     ergebnis = schreibe_puffer (meine_datei);
  234.     if (ergebnis == FALSE)
  235.     {
  236.       return (MEDIUM_VOLL);
  237.     }
  238.     ergebnis = Close (meine_datei->datei_zeiger);
  239.     if (ergebnis == FALSE)
  240.     {
  241.       return (NICHT_SCHLIESSBAR);
  242.     }
  243.     FreeMem (meine_datei->puffer_zeiger, PUFFER_GROESSE);
  244.     FreeMem (meine_datei, sizeof (struct datei));
  245.     return (KEIN_FEHLER);
  246.   }
  247. }
  248.  
  249. /* -------------------------------------------------------------------------------------- */
  250.  
  251. /*  schreibe_zeichen
  252.     Schreibt die gewⁿnschte Anzahl von Byte in die Datei die mit "*meine_datei"
  253.     ⁿbergeben wird. Rⁿckgabe ist ein Fehlercode:
  254.  
  255.     SCHREIB_FEHLER            : Datei konnte nicht geschrieben werden. Datei und
  256.                                 Pufferung defekt. Bitte schlie▀en und l÷schen.
  257.     FALSCHER_MODUS            : Datei ist mit Modus "MODE_OLDFILE" ge÷ffnet worden.
  258.                                 Es wurde keine ─nderung vorgenommen.
  259.     KEIN_FEHLER               : "anzahl" wurde zumindest in den Puffer korrekt ge-
  260.                                 schrieben.
  261. */
  262.  
  263. LONG schreibe_zeichen (struct datei *meine_datei, char *puffer, ULONG anzahl)
  264. {
  265.   LONG zaehler = 0;
  266.   BOOL ergebnis;
  267.  
  268.   if (meine_datei->modus == MODE_NEWFILE)
  269.   {
  270.     if (meine_datei->akt_position > (meine_datei->puffer_groesse - 1))
  271.     {
  272.       ergebnis = schreibe_puffer (meine_datei);
  273.       if (ergebnis == FALSE)
  274.       {
  275.         return (SCHREIB_FEHLER);
  276.       }
  277.     }
  278.     while (anzahl > 0)
  279.     {
  280.       if (meine_datei->akt_position + anzahl > meine_datei->puffer_groesse)
  281.       {
  282.         memcpy (meine_datei->puffer_zeiger + meine_datei->akt_position, puffer + zaehler,
  283.                 meine_datei->puffer_groesse - meine_datei->akt_position);
  284.  
  285.         zaehler += meine_datei->puffer_groesse - meine_datei->akt_position;
  286.         anzahl -= meine_datei->puffer_groesse - meine_datei->akt_position;
  287.  
  288.         meine_datei->akt_position += meine_datei->puffer_groesse - meine_datei->akt_position;
  289.  
  290.         ergebnis = schreibe_puffer (meine_datei);
  291.         if (ergebnis == FALSE)
  292.         {
  293.           return (SCHREIB_FEHLER);
  294.         }
  295.       }
  296.       else
  297.       {
  298.         memcpy (meine_datei->puffer_zeiger + meine_datei->akt_position,
  299.                 puffer + zaehler, anzahl);
  300.         meine_datei->akt_position += anzahl;
  301.  
  302.         return (KEIN_FEHLER);
  303.       }
  304.     }
  305.   }
  306.   else
  307.   {
  308.     return (FALSCHER_MODUS);
  309.   }
  310. }
  311.  
  312. /* -------------------------------------------------------------------------------------- */
  313.  
  314. /*  hole_byte
  315.     Holt ein einzelnes Zeichen aus der angegebenen Datei. Rⁿckgabe ist das
  316.     Zeichen oder ein Fehlercode:
  317.  
  318.     FALSCHER_MODUS                : Datei ist zum Schreiben und nicht zum
  319.                                     Lesen er÷ffnet.
  320.     DATEI_ENDE                    : Das Ende der Datei ist erreicht.
  321.     LESE_FEHLER                   : Datei konnte aus irgendeinem Grund nicht
  322.                                     gelesen werden. Datei bitte schlie▀en und
  323.                                     neu ÷ffnen.
  324. */
  325.  
  326. WORD hole_byte (struct datei *meine_datei)
  327. {
  328.   WORD zeichen;
  329.   BOOL ergebnis;
  330.  
  331.   if (meine_datei->modus == MODE_OLDFILE)
  332.   {
  333.     if (meine_datei->akt_position > (meine_datei->puffer_groesse - 1))
  334.     {
  335.       ergebnis = lese_puffer (meine_datei);
  336.       if (ergebnis == FALSE)
  337.       {
  338.         return (LESE_FEHLER);
  339.       }
  340.     }
  341.     if (meine_datei->akt_position > (LONG) (meine_datei->puffer_voelle - 1))
  342.     {
  343.       return (DATEI_ENDE);
  344.     }
  345.     zeichen = (WORD) *(meine_datei->puffer_zeiger + meine_datei->akt_position);
  346.     
  347.     meine_datei->akt_position++;
  348.     return (zeichen);
  349.   }
  350.   else
  351.   {
  352.     return (FALSCHER_MODUS);
  353.   }
  354. }
  355.  
  356. /* -------------------------------------------------------------------------------------- */
  357.  
  358. /*  schreibe_byte
  359.     Schreibt ein einzelnes Zeichen in die angegebene Datei. Liefert einen
  360.     Fehlercode zurⁿck:
  361.  
  362.     FALSCHER_MODUS          : Datei wurde zum Lesen, nicht zum Schreiben ge-
  363.                               ÷ffnet.
  364.     SCHREIB_FEHLER          : Datei konnte nicht geschrieben werden, evtl.
  365.                               Medium voll.
  366.     KEIN_FEHLER             : Zeichen konnte in den Puffer geschrieben werden.
  367. */
  368.  
  369. LONG schreibe_byte (struct datei *meine_datei, UBYTE zeichen)
  370. {
  371.   BOOL ergebnis;
  372.  
  373.   if (meine_datei->modus == MODE_NEWFILE)
  374.   {
  375.     if (meine_datei->akt_position > (meine_datei->puffer_groesse - 1))
  376.     {
  377.       ergebnis = schreibe_puffer (meine_datei);
  378.       if (ergebnis == FALSE)
  379.       {
  380.         return (SCHREIB_FEHLER);
  381.       }
  382.     }
  383.     *(meine_datei->puffer_zeiger + meine_datei->akt_position) = zeichen;
  384.     
  385.     meine_datei->akt_position++;
  386.     return (KEIN_FEHLER);
  387.   }
  388.   return (FALSCHER_MODUS);
  389. }
  390.  
  391. /* -------------------------------------------------------------------------------------- */
  392.