APPEND.MOD 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. MODULE Append;
  2. IMPORT Drectory;
  3. IMPORT HandleIO;
  4. IMPORT StringIO;
  5. IMPORT LowLevel;
  6. IMPORT M2Strings;
  7. IMPORT Numbers;
  8. IMPORT NumTypes;
  9. IMPORT EnvironUtils;
  10. IMPORT VStorage;
  11. (*
  12. IMPORT InitJPI;
  13. *)
  14. PROCEDURE AppendToFile(OldHandle : CARDINAL; DestFileName : ARRAY OF CHAR) :
  15. CARDINAL;
  16. TYPE
  17. memptr =
  18. RECORD
  19. addr : LowLevel.Address8086;
  20. size : CARDINAL;
  21. END;
  22. VAR
  23. TheDrive : CHAR;
  24. MemoryPtr : memptr;
  25. NewHandle : CARDINAL;
  26. SavedMessage : CARDINAL;
  27. FreeBytes, FileSize, DestSize, BytesToRead : LONGINT;
  28. PROCEDURE ReadOldFile(VAR MemoryPtr : memptr);
  29. VAR
  30. BytesAvailable : CARDINAL;
  31. rgstr : LowLevel.regpack;
  32. BEGIN
  33. (*ReadOldFile*)
  34. IF BytesToRead <= Numbers.Lc( 0 ) THEN
  35. MemoryPtr.addr.x := NIL;
  36. RETURN;
  37. END;
  38. BytesAvailable := EnvironUtils.MemAvail( 10000);
  39. WITH MemoryPtr DO
  40. IF BytesToRead > Numbers.Lc( BytesAvailable ) THEN
  41. size := BytesAvailable;
  42. ELSE
  43. size := Numbers.C( BytesToRead );
  44. END;
  45. VStorage.DosAlloc(addr.a, size);
  46. rgstr.c.x := size;
  47. (*CX gets number of bytes to read.*)
  48. rgstr.a.h := CHR(3FH);
  49. (*DOS Read From file Code*)
  50. rgstr.b.x := OldHandle;
  51. rgstr.d.x := addr.off;
  52. rgstr.ds := addr.seg;
  53. END;
  54. LowLevel.msdos(rgstr);
  55. IF LowLevel.FlaggedError(rgstr.flags) THEN
  56. StringIO.PrintMessage(StringIO.MessageType(rgstr.a.l));
  57. ELSE
  58. BytesToRead := BytesToRead - Numbers.Lc( MemoryPtr.size );
  59. (* Can't use DEC here because JPI doesn't allow LONGINTs
  60. to be decremented by CARDINAL values. *)
  61. END;
  62. END ReadOldFile;
  63. PROCEDURE WriteNewFile(MemoryPtr : memptr);
  64. VAR
  65. rgstr : LowLevel.regpack;
  66. BEGIN
  67. (*WriteNewFile*)
  68. IF MemoryPtr.addr.x=NIL THEN
  69. RETURN;
  70. END;
  71. rgstr.b.x := NewHandle;
  72. rgstr.c.x := MemoryPtr.size;
  73. rgstr.ds := MemoryPtr.addr.seg;
  74. rgstr.d.x := MemoryPtr.addr.off;
  75. rgstr.a.h := CHR(40H);
  76. (*Write to a file or device.*)
  77. LowLevel.msdos(rgstr);
  78. IF rgstr.a.x<rgstr.c.x THEN
  79. (*if fewer than c.x bytes were actually written*)
  80. SavedMessage := HandleIO.CloseHandle(NewHandle);
  81. StringIO.WriteEol(StringIO.outp, '');
  82. StringIO.WriteStr(StringIO.outp, 'No room.');
  83. HALT();
  84. END;
  85. VStorage.DosDealloc(MemoryPtr.addr.x, MemoryPtr.size);
  86. END WriteNewFile;
  87. BEGIN
  88. (*AppendToFile*)
  89. DestSize := Numbers.Lc( 0 );
  90. FileSize := HandleIO.FileLength(OldHandle);
  91. BytesToRead := FileSize;
  92. IF M2Strings.Pos(':',DestFileName)=(1) THEN
  93. TheDrive := DestFileName[0];
  94. ELSE
  95. TheDrive := 'Z';
  96. (*Determines the drive to which we're copying.
  97. 'Z' means "default drive" to FreeDiskSpace.*)
  98. END;
  99. SavedMessage := Drectory.FreeDiskSpace(TheDrive,FreeBytes);
  100. IF SavedMessage # StringIO.NoError THEN
  101. RETURN SavedMessage;
  102. END;
  103. SavedMessage := HandleIO.OpenFile(NewHandle,DestFileName);
  104. IF SavedMessage = StringIO.NoError THEN
  105. DestSize := HandleIO.FileLength(NewHandle);
  106. ELSE
  107. RETURN SavedMessage;
  108. END;
  109. IF FileSize > FreeBytes THEN
  110. SavedMessage := StringIO.AccessDenied;
  111. (*This will have to stand for 'Not enough room.'*)
  112. RETURN SavedMessage;
  113. END;
  114. HandleIO.SetFilePtr( NewHandle, HandleIO.FromEnd, NumTypes.L0 );
  115. IF SavedMessage # StringIO.NoError THEN
  116. RETURN SavedMessage;
  117. END;
  118. REPEAT
  119. ReadOldFile(MemoryPtr);
  120. WriteNewFile(MemoryPtr);
  121. UNTIL BytesToRead <= Numbers.Lc( 0 );
  122. RETURN HandleIO.CloseHandle(NewHandle);
  123. END AppendToFile;
  124. VAR
  125. fname1, fname2: ARRAY [0..79] OF CHAR;
  126. OldHandle : CARDINAL;
  127. BEGIN
  128. IF NOT EnvironUtils.ParsedParam( 1, fname1 ) THEN
  129. StringIO.WriteStr( StringIO.outp, 'Dest file: ' );
  130. StringIO.ReadStr( StringIO.inp, fname1 );
  131. END;
  132. IF NOT EnvironUtils.ParsedParam( 2, fname2 ) THEN
  133. StringIO.WriteStr( StringIO.outp, 'Srce file: ' );
  134. StringIO.ReadStr( StringIO.inp, fname2 );
  135. END;
  136. IF HandleIO.OpenFile( OldHandle, fname2 ) = StringIO.NoError THEN
  137. IF AppendToFile( OldHandle, fname1 ) = StringIO.NoError THEN
  138. IF HandleIO.CloseHandle( OldHandle ) = StringIO.NoError THEN
  139. StringIO.PrintMessage( Drectory.DeleteFile( fname2 ) );
  140. END;
  141. ELSE
  142. StringIO.WriteStr( StringIO.outp, 'Could not append to ' );
  143. StringIO.WriteStr( StringIO.outp, fname1 );
  144. END;
  145. ELSE
  146. StringIO.WriteStr( StringIO.outp, fname2 );
  147. StringIO.WriteStr( StringIO.outp, ' not found.' );
  148. END;
  149. END Append.