alpha version, October 2000
<<<sorry, this document is slightly out of date. Temporarily, check it please against the header file; we shall soon provide a documentation upgrade>>>
The most primitive data type is a stream--just a heap of bytes with a sequential access. It is used to support plain (MIME) files or individual streams in a stream store.
Though, being a primitive data type does not means its API should be primitive as well: quite the contrary, for sophisticated services are often needed, like
That's why the CXCStreamData API is one of the most complicated ones of all the CXC*Data classes.
-unsigned size;
This method just returns the size of the stream data in bytes, if known. Since it is quite possible the size cannot be determined, there is a symbolic constant
#define CXCUnknownSize ((unsigned)-1)
which is returned in case the size is unknown.
-CXData *read(int length=1);
Reads the specified number of bytes from the input stream and returns it as a CXCData object. The size of the returned object can be less than the length bytes in case the end of stream was encountered.
In case the stream has been read in and we are at the end, a nil is returned. Thence, the general pattern of a CXCStreamData based conversion will be
...
CXData *idata;
while ((idata=[(CXCStreamData*)_idata read])) {
...
}
// done
...
-CXData *readUpToDelimiter(CXData *delim,BOOL coalesce=NO);
Reads the bytes from the input stream up to the first occurrence of the delimiter delim. The delimiter is read from the stream (ie. the next read service will start reading after the delimiter), but is not placed at the end of the returned data object. Particularly that means that should the input stream contain just the delimiters, they will be read one after another, and an empty data object will be returned for each step.
In case the coalesce is set to YES, all the consequent delimiters are read in at once. Therefore, an empty data object will be never returned (in case there is nothing but delimiters up to the end of the input stream, nil will be returned to indicate the end of data).
Note: the coalesce=YES is not debugged thoroughly yet and probably will not work properly in this XConversion release.
-CXData *readUpToAnyDelimiter(CXArray *delims,BOOL coalesce=NO);
Just like the above service, but more delimiters can be specified. Any one of them will stop reading.
-CXData *readUpToAnyDelimiter(CXArray *delims,int *current);
Again the same, but this time delimiters cannot be coalesced. Instead the index of the delimiter which was read in is returned in the current (if current is non-NULL). In case the data was finished by the end of stream, the current will contain -1.
-void write(CXData *data);
Writes out the argument contents into the output stream.
-unsigned position;
Returns the current position in the stream; in case the stream position cannot be determined, might return a CXCUnknownSize.
-void setPosition(unsigned position);
Sets the absolute position in the stream. In case the stream does not support seeking, an exception XCStreamDataNoSeekException is raised.
-void movePositionBy(int offset);
-void setPositionToEndOfStream;
Two conveniency methods. The former sets the position relatively to the current one, the latter sets the position to the end of stream.
-XStringEncoding currentStringEncoding;
-void setCurrentStringEncoding(XStringEncoding encoding);
Determines and changes the encoding, used for text-based reading and writing. In case the encoding for the output stream is set to Unicode, the mark word (0xfeff) is automatically written out before any other text.
If the setCurrentStringEncoding is not used, the default C string encoding (see the CXString class) will be used for the reading and writing.
-CXArray *lineDelimiters;
-void setLineDelimiters(id lineDelimiters);
Determines and changes the set of strings which can serve as line delimiters. The returned set is always an array of CXData objects (!); the argument of the setLineDelimiters method can be a CXData object, a CXString object, or an array of CXData and CXString objects.
The first delimiter will be used when writing. All line delimiters are taken into account when reading.
A default value is an array of CR and LF, with LF as the first one (used for writing). It can be reset anytime by calling the setLineDelimiters with a value of nil.
There is a special hack for the MeSsy DOS crooked idea of the line delimiter: if (and only if) the default line delimiters are used (ie. the setLineDelimiter was not called at all, or was called with nil argument), the empty line between CR and LF is not returned. Thence, a text "aaa<CR>bbb<CR><LF>ccc<LF>ddd" will have four lines (not five). In case you don't want this behaviour, just set CR and LF as line delimiters manually: since it won't be the default (regardless the actual value equal to the default), the hack will not be used.
-CXString *readStringUpToDelimiter(CXString *delim,BOOL coalesce=NO);
See readUpToDelimiter above, only this time the delimiter is specified as a text string, instead of a binary data.
-CXString *readStringUpToAnyDelimiter(CXArray *delim,BOOL coalesce=NO);
See readUpToAnyDelimiter above, only this time the delimiters are specified as text strings, instead of binary data.
-CXString *readStringUpToAnyDelimiter(CXArray *delim,int *current);
See readUpToAnyDelimiter above, only this time the delimiters are specified as text strings, instead of binary data.
-CXString *readLine;
Reads in a line of text. The line delimiters are used; see the setLineDelimiters above for more details.
-void writeString(CXString *str);
-void writeFormat(CXString *str,...);
Write out the data; the former writes out just the string given, the latter interprets it just like the printf-format (and the "%@" is available, see the CXString). Each line feed character ('\n') inside the string will be replaced by the first line delimiter (see the setLineDelimiters for more details).
Note that these services does not allow to write out the character LF (since it would be replaced by the current first line delimiter). Should you really need to write it out, just use the plain write method, which writes out exactly what it got (as a CXData object).
-CXCStreamData *supplementaryDataForReadingWithName(CXString *name);
-CXCStreamData *supplementaryDataForWritingWithName(CXString *name);
Sometimes, supplementary streams are needed. These methods open them, determined by name.
The particular meaning depends on the stream type. For a plain file stream the supplementary stream is just another file; its name is determined from the receiver's filename and the name given, using the Epoc parse. Therefore, any filename part given in name will replace the appropriate part in the receiver's filename: for example, should you want to get a file with different extension, just use a name of ".newExtension".
Copyright © 1999-2000 X.soft, all rights reserved