예제 #1
0
  /**
   * primDeleteFileNamed: aFileName "Delete the file of the given name. Return self if the primitive
   * succeeds, nil otherwise."
   *
   * <p><primitive: 156> ^ nil
   */
  Object fileDelete(int argCount) {
    if (argCount != 1) throw fHandler.primitiveFailed();

    SqueakObject fileName = fHandler.stackNonInteger(0);

    File file = new File(fileName.asString());
    if (file.delete()) return fHandler.stackReceiver(argCount);

    throw fHandler.primitiveFailed();
  }
예제 #2
0
  /**
   * primCreateDirectory: fullPath "Create a directory named by the given path. Fail if the path is
   * bad or if a file or directory by that name already exists."
   *
   * <p><primitive: 'primitiveDirectoryCreate' module: 'FilePlugin'> self primitiveFailed
   */
  Object directoryCreate(int argCount) {
    if (argCount != 1) throw fHandler.primitiveFailed();

    SqueakObject fullPath = fHandler.stackNonInteger(0);

    File directory = new File(fullPath.asString());
    if (directory.mkdir()) return fHandler.stackReceiver(argCount);

    throw fHandler.primitiveFailed();
  }
예제 #3
0
  /**
   * primitiveRename: oldFileName toBe: newFileName "Rename the file of the given name if it exists,
   * else fail" <primitive: 159> self halt: 'Attempt to rename a non-existent file, or to use a name
   * that is already in use'!
   */
  Object fileRename(int argCount) {
    if (argCount != 2) throw fHandler.primitiveFailed();

    SqueakObject oldName = fHandler.stackNonInteger(1);
    SqueakObject newName = fHandler.stackNonInteger(0);

    File file = new File(oldName.asString());
    if (file.renameTo(new File(newName.asString()))) return fHandler.stackReceiver(argCount);

    throw fHandler.primitiveFailed();
  }
예제 #4
0
  /**
   * primGetPosition: id "Get the receiver's current file position. 2/12/96 sw" <primitive: 152> ^
   * self primitiveFailed!
   */
  Object getPosition(int argCount) {
    if (argCount != 1) throw fHandler.primitiveFailed();

    RandomAccessFile file = lookupFile();
    try {
      return fHandler.pos32BitIntFor(file.getFilePointer());
    } catch (IOException e) {
      e.printStackTrace();
    }

    throw fHandler.primitiveFailed();
  }
예제 #5
0
  /**
   * primAtEnd: id "Answer whether the receiver is currently at its end. 2/12/96 sw"
   *
   * <p><primitive: 150> ^ self primitiveFailed!
   */
  Object fileAtEnd(int argCount) {
    if (argCount != 1) throw fHandler.primitiveFailed();

    RandomAccessFile file = lookupFile();
    try {
      return fHandler.squeakBool(file.getFilePointer() >= file.length());
    } catch (IOException e) {
      e.printStackTrace();
    }

    throw fHandler.primitiveFailed();
  }
예제 #6
0
  /**
   * primClose: anID "Primitive call to close the receiver. 2/12/96 sw" <primitive: 151> ^ self
   * primitiveFailed!
   */
  Object fileClose(int argCount) {
    if (argCount != 1) throw fHandler.primitiveFailed();

    RandomAccessFile file = lookupFile();
    try {
      file.close();

      // Pharo seems to return self, so let's do the same
      return fHandler.stackReceiver(1);
    } catch (IOException e) {
      e.printStackTrace();
    }

    throw fHandler.primitiveFailed();
  }
예제 #7
0
  /**
   * primSetPosition: id to: aNumber "Set the receiver's file position to be a Number. 2/12/96 sw"
   * <primitive: 155> ^ self primitiveFailed!
   */
  Object fileSetPosition(int argCount) {
    if (argCount != 2) throw fHandler.primitiveFailed();

    RandomAccessFile file = lookupFile(1);
    int pos = fHandler.stackPos32BitValue(0);

    try {
      file.seek(pos);
      return fHandler.stackReceiver(argCount);
    } catch (IOException e) {
      e.printStackTrace();
    }

    throw fHandler.primitiveFailed();
  }
예제 #8
0
  /**
   * Array with
   *
   * <p><name> <creationTime> <modificationTime> <dirFlag> <fileSize>
   *
   * <p>See {@link #lookupEntryInIndex(int)}
   */
  private SqueakObject makeDirectoryEntryArray(File file) {
    // bah, Java doesn't provide the creation time.  If it is
    // really necessary, it may be possible to use java-posix or
    // jtux.
    String name = file.getName();
    long creationTime = file.lastModified();
    long modificationTime = file.lastModified();
    boolean dirFlag = file.isDirectory();
    long fileSize = file.length();

    try {
      Object[] array = {
        fHandler.makeStString(name),
        fHandler.squeakSeconds(creationTime),
        fHandler.squeakSeconds(modificationTime),
        fHandler.squeakBool(dirFlag),
        fHandler.pos32BitIntFor(fileSize)
      };

      return fHandler.squeakArray(array);
    } catch (ArrayIndexOutOfBoundsException e) {
      System.out.println(
          "Error in FileSystemPrimitives.makeDirectoryEntryArray: name = '" + name + "'");
      throw e;
    }
  }
예제 #9
0
  /**
   * lookupEntryIn: pathName index: index "Look up the index-th entry of the directory with the
   * given path (starting from the root of the file hierarchy) and return an array containing:
   *
   * <p><name> <creationTime> <modificationTime> <dirFlag> <fileSize>
   *
   * <p>The creation and modification times are in seconds since the start of the Smalltalk time
   * epoch. DirFlag is true if the entry is a directory. FileSize the file size in bytes or zero for
   * directories. The primitive returns nil when index is past the end of the directory. It fails if
   * the given pathName is bad."
   *
   * <p><primitive: 162> self primitiveFailed.!
   */
  Object lookupEntryInIndex(int argCount) {
    if (argCount != 2) throw fHandler.primitiveFailed();

    SqueakObject fullPath = fHandler.stackNonInteger(1);
    int index = fHandler.stackInteger(0) - 1;

    if (index < 0) throw fHandler.primitiveFailed();

    String filename = fullPath.asString();
    if (filename.trim().length() == 0) filename = "/";

    File directory = new File(fullPath.asString());
    if (!directory.exists()) throw fHandler.primitiveFailed();

    File[] paths = directory.listFiles();
    if (index < paths.length) return makeDirectoryEntryArray(paths[index]);

    return fHandler.squeakNil();
  }
예제 #10
0
  /**
   * primOpen: fileName writable: writableFlag "Open a file of the given name, and return the file
   * ID obtained. If writableFlag is true, then if there is none with this name, then create one
   * else prepare to overwrite the existing from the beginning otherwise if the file exists, open it
   * read-only else return nil"
   *
   * <p><primitive: 153> ^ nil
   */
  Object openWritable(int argCount) {
    if (argCount != 2) throw fHandler.primitiveFailed();

    SqueakObject fileName = fHandler.stackNonInteger(1);
    SqueakObject writableFlag = fHandler.stackNonInteger(0);

    String mode = fHandler.javaBool(writableFlag) ? "rw" : "r";
    try {
      RandomAccessFile file = new RandomAccessFile(fileName.asString(), mode);
      SqueakObject fileId = fHandler.makeStString("fileId: " + fileName.asString());
      setFile(fileId, file);

      return fileId;
    } catch (FileNotFoundException e) {
      System.err.println(e.getMessage());
    }

    throw fHandler.primitiveFailed();
  }
예제 #11
0
  /**
   * primWrite: id from: byteArray startingAt: startIndex count: count "Write into the receiver's
   * file from the given area of storage, starting at the given index, as many as count bytes;
   * return the number of bytes actually written. 2/12/96 sw"
   *
   * <p><primitive: 158>
   *
   * <p>closed ifTrue: [^ self halt: 'Write error: File not open']. rwmode ifFalse: [^ self halt:
   * 'Error-attempt to write to a read-only file.']. self halt: 'File write error'! !
   */
  Object fileWrite(int argCount) {
    if (argCount != 4) throw fHandler.primitiveFailed();

    RandomAccessFile file = lookupFile(3);
    SqueakObject byteArray = fHandler.stackNonInteger(2);
    int startIndex = fHandler.stackInteger(1) - 1; // zero based
    int count = fHandler.stackInteger(0);

    try {
      int written = 0;
      for (int index = startIndex; index < startIndex + count; index++) {
        file.write(byteArray.getByte(index));
        written++;
      }

      return fHandler.pos32BitIntFor(written);
    } catch (IOException e) {
      e.printStackTrace();
    }

    throw fHandler.primitiveFailed();
  }
예제 #12
0
  /**
   * primRead: id into: byteArray startingAt: startIndex count: count "read from the receiver's file
   * into the given area of storage, starting at the given index, as many as count bytes; return the
   * number of bytes actually read. 2/12/96 sw"
   *
   * <p><primitive: 154>
   *
   * <p>self halt: 'error reading file'!
   */
  Object readIntoStartingAtCount(int argCount) {
    if (argCount != 4) throw fHandler.primitiveFailed();

    SqueakObject byteArray = fHandler.stackNonInteger(2);
    int startIndex = fHandler.stackInteger(1) - 1;
    int count = fHandler.stackInteger(0);

    RandomAccessFile file = lookupFile(3);

    byte[] buffer = new byte[count];
    try {
      int read = file.read(buffer, 0, count);

      for (int index = 0; index < read; index++) {
        byteArray.setByte(startIndex + index, buffer[index]); // FIXME: this code cheats!
      }

      return fHandler.pos32BitIntFor(read);
    } catch (IOException e) {
      e.printStackTrace();
    }

    throw fHandler.primitiveFailed();
  }
예제 #13
0
  /** @return the file associated with the file ID in the given stack position */
  private RandomAccessFile lookupFile(int stackDepth) {
    SqueakObject fileId = fHandler.stackNonInteger(stackDepth);
    if (!fFiles.containsKey(fileId)) throw fHandler.primitiveFailed();

    return (RandomAccessFile) fFiles.get(fileId);
  }
예제 #14
0
 /**
  * actualPathNameDelimiter "Return the path delimiter for the underlying file system." <primitive:
  * 161> self primitiveFailed.!
  */
 SqueakObject directoryDelimitor() {
   return fHandler.charFromInt((int) File.separatorChar);
 }