Copyright © 1997 The California Institute of Technology
All rights reserved.

Class: Fei


Version 3.01

This is the main class in the FEI application program interface (API). It's used to

the contents of files. transaction. already exists locally.

FEI status values are returned by many of the methods in this class. Status values are also part of each profile record associated with a file. The status values that can be returned are:

Commands can be queued until Fei's internal request queue is filled. If any attempt to queue a command returns FEI_ERROR, and errno is set to EAGAIN, that means you can try to re-queue your command later. You might try to get some results from fei first.

An Fei connection is to one file type at a time. See also FeiProfile, FeiMsg, FeiDomain.

For more information on the class, see the header file: Fei.h


int Fei::_notify (const char *localPath, const char *restartFileName,
bool optionToGetFile)

Internal method for implementing notify and liveList methods.


int Fei::acceptTheFile (FeiProfile *fileProfile)

Used after getting a profile object back in a notify session. Tells Fei to get the file named in the profile record. The argument to this method is the notify profile record for the file. The next profile object returned following this call, is the profile object for the file requested. Here's a code fragment that shows how this works:

 fei.notify (myFileType, myRestartFile);
 FeiProfile *profile;
 while (fei.results (delayTime)) {
	  if (shouldGetFile (profile->fileName)) {
			profile = fei.result ();
			fei.acceptTheFile (profile);
	  } else {
			profile = fei.result ();
			fei.rejectTheFile (profile);
	  }
	  if (profile) delete profile;
 }

The result () method in the while loop is associated with the notify session. That's check in some way and then either we get or reject the file. The profile record in the if statement is assoicated with the request to get or reject the file.

Note: This method deletes the profile record supplied as its argument. That's why we were able to reuse the variable profile in the example without first deleting the profile object supplied to acceptTheFile() or rejectTheFile(). We follow a simple rule in all cases: "Profile objects passed back from Fei are managed by the caller. Those passed to Fei are managed by the Fei object."


int Fei::add (const char *feiFileName, void *address, size_t size)

Queue an add file request, where the contents of the file is located in memory. The starting address is supplied as address and the length of the buffer is given as size. Queues a profile record upon completion.

Returns FEI_OK upon success; FEI_WARN if the address is NULL or the size is 0; FEI_ERROR otherwise.

See also replace, transaction, result.


int Fei::addOption (const int option)

Adds a single option to the current set of options. To redefine all options use setOptions. Returns the new set of options. See also isOption.


int Fei::connect (const char *fileType, const char *feiDomain, bool useFeiEnv)

Connect to an FEI server for the supplied file type. The feiDomain value is usually NULL in which case the default domain file feiDomain used. The environmental variable FEI provides the directory path to feiDomain. Returns FEI_OK if a connection is made. Otherwise it returns a an FEI status value greater than FEI_OK.

See also isConnected, disconnect, restart


int Fei::disconnect ()

Disconnects from an FEI server. All unprocessed commands will be marked FEI_CANCELLED and queued to the result queue. Returns FEI_OK.

See also isConnected, connect.


Fei::Fei ()

Constructor. Allocates and initializes a new Fei object. To make a connection with the new object use connect. Also see the special case for restart.


int Fei::get (const char *feiFileExpression, const char *localPath, const char *since)

Queues a get files command for the file type associated with this connection. Gets all files matching feiFileExpressions and places them into the directory specified by localPath. To use the current working directory for the destination of the files, supply a localPath value of ".". If a value for the optional parament since is supplied, only files with an FEI modified time later than that are returned.allows files to be retrieved after a specific date. Returns FEI_OK upon success, FEI_ERROR otherwise.

A profile record is queued for each file returned.

If a description of the files is supplied in the FEI database, it is returned along with other file information in the file's profile object. Returns FEI_OK if the command can be posted.

See also transactions, result, options`.


inline int Fei::getErrno (void)

Returns the current error number associated with this object. If there is no error, the value is 0. You can clear the error number - and error message - with the method resetError ()

See also getMsg.


inline const char *Fei::getFileType (void)

Returns a pointer to the current Fei file type, or (const char *) NULL if there isn't one.


inline const char *Fei::getMsg (void)

Returns the address of Fei's message buffer. Often used when Fei is composited in another class and that class must report an error through Fei: ie, NetClient. See also setErrno. Returns the error message associated with the last error. If currently there is no error, (const char *)NULL is returned. You can clear the error message buffer with the method resetStrerror ().

See also getErrno.


bool Fei::isConnected ()

Returns true is the object is connected to an FEI server, false otherwise.


bool Fei::isOption (const int option)

isOption () returns true if the option specified is set. Returns false otherwise. See also setOptions.


int Fei::list (const char *feiFileExpression, const char *since)

Queue a list files command that matches the supplied file name, or a regular expression. If since is specified, then only list files with an FEI modified time later than that. Returns FEI_OK on success, FEI_ERROR othewise.

Each file name found is returned in a separately queued profile object.

See also transactions, result.


int Fei::liveList (const char *restartFileName)

Get a list of files as they come in to the file type associated with this connection. Information about each is queued as a profile. The profile records are saved into a restartFile for that can be to restart a live list. Returns FEI_OK if the command can be posted.

See also restart, result.


int Fei::notify (const char *localPath, const char *restartFileName)

Get a list of files when they come in to the file type associated with this connection. Information about each is queued as a profile. The caller must then call Fei::acceptTheFile (FeiProfile *) or Fei::rejectTheFile. Fei will then retrieve the file and re-queue the profile with the result of the get operation, or delete the profile. In both cases, the profile record is saved into a restartFile for that can be to restart a notification. Returns FEI_OK if the command can be posted.

See also restart, result, acceptTheFile, rejectTheFile.


int Fei::rejectTheFile (FeiProfile *fileProfile)

Tell FEI that you don't want the file described in a notify profile object. See the member function acceptTheFile for example of this functions use in a notify session.

The profile record passed to rejectTheFile is deleted by the method since control of the object is passed back to Fei.

See also, notify, acceptTheFile.


int Fei::remove (const char *feiFileExpression)

Remove (delete) files from the file type associated with the current connection. You can supply a file name or a regular expression matching a set of file names in FEI. The result of each delete operation is queued as a profile record. Returns FEI_OK upon success, FEI_ERROR otherwise.

Note: This method performs the FEI delete operation. It's called remove in this API because delete is a C++ reserved word.

See also transaction, result.


int Fei::rename (const char *fileName, const char *newFileName)

Rename a file associated with the file type for the current connection. The first parameter is the old file name and the second parameter is the new file name. The result of this operation is queued as a profile record. Returns FEI_OK upon success, FEI_ERROR otherwise.

Note: A file can only be renamed within a file type. To rename a file and move it to another file type, you must get the file, add it to the new file type using the new name and then delete the old file.

See also transaction, result.


int Fei::replace (const char *feiFileName, void *address, size_t size)

Queue a replace file request, where the contents of the file is located in memory. The starting address is supplied as address and the length of the buffer is given as size. Queues a profile record upon completion.

The caller is responsible for managing the buffer space used for the file's contents. Fei does not allocate nor free the space. The result of this operation is queued as a profile record. Returns FEI_OK upon success; FEI_WARN if the address is NULL or the size is 0; FEI_ERROR otherwise.

See also add, transaction, result.


inline void Fei::resetError (void)

Resets the errno value and the string error buffer for the object.

See also getErrno (), getMsg.


int Fei::restart (const char *restartFile)

Restarts a subscription or notify session using the state information stored in a restart file produced by a previous subscription or notify session. You must supply a localPath for the restarted session.

When restarting a subscription or notify session, this command first gets all files received by FEI since the end of the last session recorded in the restart file. It then starts a new subscription session. A profile record is queued for each file returned. Restarting a notify session works the same way, except files are not returned, only profile records.

For notify only, you can provide a value {true | false} for the third argument optionToGetFile. By default this argument is false. If you provide a third argument when establishing a subscription session, the value of the argument is ignored.

Do not connect to FEI before issuing this command. Connection is part of the restart process. If you are connected with the Fei object and then issue this command, you will receive a status value of FEI_ERROR and the command will fail. For a new session, you create the object and issue a restart command:

  Fei fei;
  fei.restart (myRestartFile, myLocalPath);
If this is a restart for notify, you can provide a value for optionToGetFile as well:
  fei.restart (myRestartFile, myLocalPath, true);
If your already connected to FEI think you might be, the you must disconnect before starting a restart session using an existing Fei object. For a subscription session:
  if (fei.isConnected ())
		fei.disconnect ();
  fei.restart ((myRestartFile, myLocalPath);
or, for a notify session using the optional third argument:
  if (fei.isConnected ())
		fei.disconnect ();
  fei.restart ((myRestartFile, myLocalPath, true);
Returns FEI_OK upon success, FEI_ERROR otherwise.

See also subscription, notify.


FeiProfile *Fei::result (long delay)

Once you queue a request to transmit a file or after you start a subscription or notify session, Fei returns a set of results. A result set consist of a profile object for each file acted upon plus a final NULL object. (If your request returns no results, the final NULL object is still returned, so the result set always contains at least one queued object, in this case, just the null object.) You retrieve the profile records in the queue using the member function result, with an optional delay time argument. (The delay time is in seconds.) Each call to result returns one profile record, so to get all the queued profile records, a loop is used like so:

  FeiProfile *profile;
  while (profile = fei.result () != (FeiProfile *)NULL) {
		if (profile->getStatus != FEI_OK) {
			 reportError (profile);
			 delete profile;
			 profile = (FeiProfile *)NULL;
		}
		else
			 doSomething (profile);
		delete profile;
  }

In the example (FeiProfile *)NULL is the value of the NULL profile record marking the end of the result set. We continue to get results until we reach the (FeiProfile *)NULL point, indicating that there are no more profiles associated with our transaction.

Notice that the calling function deletes the profile object. Since Fei has handed the profile object off to the caller, it is the caller's responsibility to reclaim the memory used by the object once it's no longer needed.

Since we did not supply a delay time argument to result, it blocks until the Fei object returns a profile record. This form of calling the method simulates single-threaded, synchronous behavior. If a delay time were supplied,

  long delay = 5; // seconds
  profile = fei.result (delay);
  if (profile != (FeiProfile *)NULL) {
		doSomething (profile);
		delete profile;
  }

result () would have waited up to 5 seconds, and then it would have returned, regardless of whether or not a profile object had been queued. We could then come back later and check again for a result. ('Note:' If you want to check for a result and return immediately no matter what the outcome, use a delay value of 0.)

result () returns either a profile object describing a file or the NULL profile object represented by (FeiProfile *)NULL. Note: you should not attempt to delete the NULL profile record.

See also, transactions, class FeiProfile.


int Fei::setOptions (const int mask)

setOptions () adds the or'ed options specified in the mask to the current options mask. New options affect new commands only. Commands already queued operate under the old options. (Fei.h includes FeiProfile.h, so the values are defined in this context as well.) Valid option values are:

during transmission. (The CRC value is part of the file's profile record and can be optained using the FeiProfile member function getCrc (). The next three options determine what an Fei object does when it returns a file to the client and finds an existing file with the same name as the file returned.

file and then write the new file using the file name.

feiReplace, feiSkip and feiVersion, are mutually exclusive. If you attempt to define more than one, the following precedence rule is applied when setting the mask value: feiSkip: feiVersion : feiReplace - with feiSkip having the highest precedence.

setOption () returns the current options mask. Initially, only one option is set, feiSkip. Calling setOption () without an argument, resets the option mask to this initial state. See also addOption, isOption.

Here's an example using the member function setOption ():

  int oldMask = fei.setOption (encrypt | crc | feiReplace);
  doSomething (&fei);
  fei.setOption (oldMask);


int Fei::subscribe (const char *localPath, const char *restartFileName)

Start a subscription session for the file type associated with the connection. Information about each file retrieved is queued as a profile record. Returns FEI_OK upon success, FEI_ERROR otherwise.

If the localPath argument is FEI_IN_MEMORY, the file returned as a buffer associated with the file's profile object. Use the FeiProfile member function getAddress() to get the starting address of the file's contents in this case, and getSize() to get the size of the buffer. Note: The buffer is not NULL terminated because FEI assumes no special characters for a file's contents. The file's contents are deleted when the profile record is deleted unless you first reset the address in the profile object using the member function setAddress ((void *)NULL). In that case, you are responsible for deleting the buffer later on. Use delete and not free to do this.

If a restart file name is supplied, the state of the subscription session is record in a file by that name. You can use the restart() command to restart the session from that state later on with a new Fei object.

See also restart, notify, transactions, result, setOption.


int Fei::transactions (void)

Returns the number of transactions queued and not yet completed. A transaction is removed from the queue once all results associated with the transaction are returned. This member function is used to detect the end of a transaction when multiple results can be returned. In the following example, we get back a lists of files. We continue to check for results as long as the transaction is still queued: ie, until all files are returned. Whenever a file is returned we so something with it. In the mean time, we go off and do something else. transaction always returns immediately. If the transaction queue is empty, 0 is returned, otherwise the number of pending transactions is returned

  fei.get ("file.*", .);
  while (fei.transactions () != 0) {
		while (fei.result (0) != (FeiProfile *)NULL) {
			 if (profile)
				  doSomething (profile);
			 else
				  doSomethingElse ();
		}
  }

See also result.