home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Misc / Split_GUI.lha / Split_v1.0 / Sources.lha / Sources / split.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-22  |  5.9 KB  |  249 lines

  1. #include <exec/memory.h>
  2. #include <intuition/intuition.h>
  3. #include <libraries/gadtools.h>
  4.  
  5. #include <proto/exec.h>
  6. #include <proto/dos.h>
  7. #include <proto/intuition.h>
  8. #include <proto/gadtools.h>
  9. #include <clib/alib_protos.h>
  10. #include <string.h>
  11.  
  12. #include "split.h"
  13.  
  14. /* for debug purposes */
  15. #include <stdio.h>
  16.  
  17. extern struct Window *window;
  18. extern struct Gadget *glist, *gad, *vlist_gad, *chunk_gad, *chunknum_gad,
  19.     *chunksize_gad, *chunkoffs_gad, *write_gad, *chunknam1_gad, *chunknam2_gad,
  20.     *filenam1_gad, *filenam2_gad, *filesize_gad, *status_gad;
  21.  
  22. extern struct List *vlist;
  23. extern struct List *getVolumeList( struct List * );
  24.  
  25. extern struct EasyStruct easyr;
  26.  
  27.  
  28. char filename[128];
  29. ULONG filesize;
  30.  
  31. ULONG chunkwritten;
  32.  
  33. STRPTR status_title, msg_warnmangledsource, msg_warnmangleddest, msg_ok;
  34. STRPTR statname[4];
  35.  
  36. UBYTE status = STATUS_IDLE;
  37.  
  38. char chunkname[128];
  39. UBYTE chunk_number = 1;
  40. ULONG chunksize, chunkoffset;
  41.  
  42. struct Header header;
  43.  
  44. struct chunkNode {
  45.     struct Node cn_Node;
  46.     ULONG cn_Size;
  47.     ULONG cn_Offset; };
  48.  
  49. struct List chunkList;
  50.  
  51.  
  52. void readyChunkList( void )
  53. {
  54. NewList( &chunkList );
  55. }
  56.  
  57.  
  58. void insertChunkList( ULONG csize, ULONG coffs )
  59. {
  60. struct chunkNode *newnode, *node;
  61. if ( newnode = AllocVec( sizeof(struct chunkNode), MEMF_ANY|MEMF_CLEAR ) )
  62.     {
  63.     newnode->cn_Size = csize;
  64.     newnode->cn_Offset = coffs;
  65.     node = (struct chunkNode *)chunkList.lh_Head;
  66.     while( node->cn_Node.ln_Succ && node->cn_Offset < coffs )
  67.         node = (struct chunkNode *)node->cn_Node.ln_Succ;
  68.     Insert( &chunkList, newnode, node );
  69.     }
  70. }
  71.  
  72.  
  73. void newChunkList( void )
  74. {
  75. insertChunkList( filesize, 0 );
  76. }
  77.  
  78.  
  79. void freeChunkList( void )
  80. {
  81. struct chunkNode *cn;
  82. while( cn = (struct chunkNode *)RemHead( &chunkList ) )
  83.     FreeVec( cn );
  84. }
  85.  
  86.  
  87. void clearHeader( void )
  88. {
  89. memset( &header, 0, sizeof(struct Header) );
  90. header.h_Identifier = (ULONG)(('S'<<24)+('P'<<16)+('L'<<8)+'0');
  91. }
  92.  
  93.  
  94. void updateGadgets( void )
  95. {
  96. if ( window )
  97.     {
  98.     if ( !filesize )
  99.         OffGadget( write_gad, window, NULL );
  100.     else
  101.         OnGadget( write_gad, window, NULL );
  102.  
  103.     GT_SetGadgetAttrs( chunknum_gad, window, NULL, GTNM_Number, chunk_number, TAG_END );
  104.     GT_SetGadgetAttrs( chunksize_gad, window, NULL, GTIN_Number, chunksize, TAG_END );
  105.     GT_SetGadgetAttrs( chunkoffs_gad, window, NULL, GTIN_Number, chunkoffset, TAG_END );
  106.     GT_SetGadgetAttrs( chunknam2_gad, window, NULL, GTST_String, chunkname, TAG_END );
  107.     GT_SetGadgetAttrs( filenam2_gad, window, NULL, GTTX_Text, FilePart(filename), TAG_END );
  108.     GT_SetGadgetAttrs( filesize_gad, window, NULL, GTNM_Number, filesize, TAG_END );
  109.     GT_SetGadgetAttrs( status_gad, window, NULL, GTTX_Text, statname[status], TAG_END );
  110.     }
  111. }
  112.  
  113.  
  114. BOOL checkChunk( void )
  115. {
  116. struct chunkNode *node = (struct chunkNode *)chunkList.lh_Head;
  117. while( node->cn_Node.ln_Succ && node->cn_Offset + node->cn_Size < chunkoffset )
  118.     {
  119.     node = (struct chunkNode *)node->cn_Node.ln_Succ;
  120.     }
  121. if ( !node->cn_Node.ln_Succ )
  122.     /* An error within list ??? */
  123.     return FALSE;
  124. else if ( node->cn_Offset + node->cn_Size < chunkoffset + chunksize )
  125.     return FALSE;
  126. else
  127.     return TRUE;
  128. }
  129.  
  130.  
  131. void getNextChunk( void )
  132. {
  133. struct chunkNode *node = (struct chunkNode *)chunkList.lh_Head;
  134. chunkoffset = node->cn_Offset;
  135. chunksize = node->cn_Size;
  136. updateGadgets();
  137. }
  138.  
  139.  
  140. void goIdle( void )
  141. {
  142. clearHeader();
  143. freeChunkList();
  144. filesize = 0;
  145. filename[0] = 0;
  146. chunkname[0] = 0;
  147. chunkwritten = 0;
  148. status = STATUS_IDLE;
  149. chunk_number = 1;
  150. updateGadgets();
  151. }
  152.  
  153.  
  154. void writeNextChunk( void )
  155. {
  156. UBYTE *mptr;
  157. ULONG bytes_copied = 0, bytes_transferred, bytes_to_transfer;
  158. BPTR source, dest;
  159. BOOL mustDelete = FALSE;
  160.  
  161. if ( filesize && ( mptr = AllocVec( TRANSFER_SIZE, MEMF_ANY ) ) )
  162.     {
  163.     strcpy( FilePart(chunkname), FilePart(filename) );
  164.     strcat( chunkname, ".00" );
  165.  
  166.     chunkname[strlen(chunkname)-1] = (chunk_number%10) + '0';
  167.     chunkname[strlen(chunkname)-2] = (chunk_number/10) + '0';
  168.  
  169.     if ( source = Open( filename, MODE_OLDFILE ) )
  170.         {
  171.         if ( dest = Open( chunkname, MODE_NEWFILE ) )
  172.             {
  173.             strcpy( header.h_FileName, FilePart(filename) );
  174.             header.h_FileSize = filesize;
  175.             header.h_ChunkStart = chunkoffset;
  176.             header.h_ChunkEnd = chunkoffset + chunksize;
  177.             Write( dest, &header, sizeof(struct Header) );
  178.  
  179.             Seek( source, chunkoffset, OFFSET_BEGINNING );
  180.             while ( bytes_copied != chunksize )
  181.                 {
  182.                 status = STATUS_READING;
  183.                 updateGadgets();
  184.                 bytes_to_transfer = ( chunksize - bytes_copied > TRANSFER_SIZE ? TRANSFER_SIZE : chunksize - bytes_copied );
  185.                 bytes_transferred = Read( source, mptr, bytes_to_transfer );
  186.                 if ( bytes_transferred != bytes_to_transfer )
  187.                     {
  188.                     easyr.es_TextFormat = msg_warnmangledsource;
  189.                     easyr.es_GadgetFormat = msg_ok;
  190.                     EasyRequestArgs( window, &easyr, NULL, NULL );
  191.                     goto end;
  192.                     }
  193.                 status = STATUS_WRITING;
  194.                 updateGadgets();
  195.                 bytes_transferred = Write( dest, mptr, bytes_to_transfer );
  196.                 if ( bytes_transferred != bytes_to_transfer )
  197.                     {
  198.                     easyr.es_TextFormat = msg_warnmangleddest;
  199.                     easyr.es_GadgetFormat = msg_ok;
  200.                     EasyRequestArgs( window, &easyr, NULL, NULL );
  201.                     mustDelete = TRUE;
  202.                     goto end;
  203.                     }
  204.                 bytes_copied += bytes_transferred;
  205.                 }
  206.             status = STATUS_SPLITTING;
  207.  
  208.             chunkwritten += chunksize;
  209.             if ( chunkwritten == filesize )
  210.                 goIdle();
  211.             else
  212.                 {
  213.                 struct chunkNode *node = (struct chunkNode *)chunkList.lh_Head;
  214.                 while( node->cn_Offset > chunkoffset )
  215.                     node = (struct chunkNode *)node->cn_Node.ln_Succ;
  216.                 if ( node->cn_Offset == chunkoffset )
  217.                     {
  218.                     if ( node->cn_Size == chunksize )
  219.                         Remove( node );
  220.                     else
  221.                         {
  222.                         node->cn_Offset += chunksize;
  223.                         node->cn_Size -= chunksize;
  224.                         }
  225.                     }
  226.                 else
  227.                     {
  228.                     if ( node->cn_Offset + node->cn_Size == chunkoffset + chunksize )
  229.                         node->cn_Size -= chunksize;
  230.                     else
  231.                         {
  232.                         insertChunkList( node->cn_Offset + node->cn_Size - chunkoffset - chunksize, chunkoffset + chunksize );
  233.                         node->cn_Size = chunkoffset - node->cn_Offset;
  234.                         }
  235.                     }
  236.                 chunk_number++;
  237.                 getNextChunk();
  238.                 }
  239. end:
  240.             Close( dest );
  241.             if ( mustDelete )
  242.                 DeleteFile( chunkname );
  243.             }
  244.         Close( source );
  245.         }
  246.     FreeVec( mptr );
  247.     }
  248. }
  249.