PCPSTREAMS

I/O wrapper for files or buffers. More...

Functions

Pcpstreamps_new_file (FILE *backendfd)
 Create a new stream, backed with an open file. More...
 
Pcpstreamps_new_inbuffer (Buffer *b)
 Create a new input stream, backed with filled a buffer. More...
 
Pcpstreamps_new_outbuffer ()
 Create a new output stream, backed with a buffer. More...
 
size_t ps_read (Pcpstream *stream, void *buf, size_t readbytes)
 Read bytes into the given buffer from the current stream. More...
 
size_t ps_write (Pcpstream *stream, void *buf, size_t writebytes)
 Write bytes from the given buffer into the current stream. More...
 
size_t ps_finish (Pcpstream *stream)
 Finalize writing the stream. More...
 
size_t ps_print (Pcpstream *stream, const char *fmt,...)
 Write a formatted string to the stream. More...
 
size_t ps_tell (Pcpstream *stream)
 Tell the current read or write offset. More...
 
Bufferps_buffer (Pcpstream *stream)
 Access the Buffer backend pointer. More...
 
void ps_close (Pcpstream *stream)
 Close the stream and frees allocated memory. More...
 
int ps_end (Pcpstream *stream)
 Check if EOF have been reached. More...
 
int ps_err (Pcpstream *stream)
 Check if an error occurred during a read or write operation. More...
 
void ps_setdetermine (Pcpstream *stream, size_t blocksize)
 Enable auto Z85 encoding detection for an input stream. More...
 
void ps_armor (Pcpstream *stream, size_t blocksize)
 Enable Z85 encoding for an output stream. More...
 
void ps_unarmor (Pcpstream *stream)
 Disable Z85 encoding for an output stream. More...
 
int ps_readline (Pcpstream *stream, Buffer *line)
 Read a line from the stream. More...
 

Detailed Description

I/O wrapper for files or buffers.

Simple wrapper around FILE streams or Buffers, depending how the user initialized them. The Pcpstream object behaves always the same and it doesn't matter how it's backed.

We use it in the lib, e.g. in the crypto routines. That way we can support blockwise crypto on buffers or files.

Streams are, just like iostreams in c++, either output or input mode.

Sample usage:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <pcp.h>
int main() {
/* create a file with "encrypted" data */
FILE *out, *in;
unsigned char clear[8] = "ABCDEFGH";
unsigned char key[8] = "IxD8Lq1K";
unsigned char crypt[8] = {0};
int blocks = 8;
size_t blocksize = 4;
int i = 0;
if((out = fopen("teststream.out", "wb+")) == NULL) {
fprintf(stderr, "oops, could not open file!\n");
return 1;
}
/* out output stream, z85 encoded, use z85 blocksize 8 */
Pcpstream *pout = ps_new_file(out);
ps_print(pout, "----- BEGIN -----\r\n");
ps_armor(pout, blocksize);
/* "encrypt" a couple of times into the output stream */
for(i=0; i<blocks; i++) {
memcpy(crypt, clear, 8);
_xorbuf(key, crypt, 8);
ps_write(pout, crypt, 8);
}
/* done, put cached buffers out and close */
ps_finish(pout);
pout->armor = 0;
ps_print(pout, "\r\n----- END -----\r\n");
ps_close(pout);
fclose(out);
/* read it in again using an input stream */
if((in = fopen("teststream.out", "rb")) == NULL) {
fprintf(stderr, "oops, could not open file!\n");
return 1;
}
Pcpstream *pin = ps_new_file(in);
/* enable autmatically encoding detection. */
ps_setdetermine(pin, blocksize);
/* we'll use this stream to put the "decrypted" data in.
note, that this could be a file as well. */
/* read and "decrypt" */
for(i=0; i<blocks; i++) {
ps_read(pin, crypt, 8);
_xorbuf(key, crypt, 8);
ps_write(pclear, crypt, 8);
memset(crypt,0,8);
}
ps_close(pin);
fclose(in);
/* now extract the buffer from the output stream */
Buffer *result = ps_buffer(pclear);
/* and verify if it's "decrypted" (re-use crypt) */
for(i=0; i<blocks; i++) {
buffer_get_chunk(result, crypt, 8);
if(memcmp(crypt, clear, 8) != 0) {
fprintf(stderr, "Oops, block %d doesn't match\n", i);
goto error;
}
}
ps_close(pclear);
fprintf(stderr, "done\n");
return 0;
error:
ps_close(pclear);
return 1;
}

Function Documentation

void ps_armor ( Pcpstream stream,
size_t  blocksize 
)

Enable Z85 encoding for an output stream.

Parameters
[in]streamThe stream object.
[in]blocksizeThe blocksize to for Z85 encoding.
Buffer* ps_buffer ( Pcpstream stream)

Access the Buffer backend pointer.

Use this function to access the underlying Buffer object of an output stream to access the contents written to it. Only usefull if the stream have been initialized with ps_new_outbuffer().

Parameters
[in]streamThe stream object.
Returns
Returns a pointer to the Buffer object.
void ps_close ( Pcpstream stream)

Close the stream and frees allocated memory.

If the backend of the stream was a FILE stream, close it, unless it is stdin, stdout or stderr.

If the backend was a Buffer, clear and free it.

Parameters
[in]streamThe stream to close.
int ps_end ( Pcpstream stream)

Check if EOF have been reached.

This function can be used to check if there are no more bytes to read. This will happen if we reach EOF with a FILE backed stream or buffer_done() with a Buffer backed stream.

Parameters
[in]streamThe stream object.
Returns
Returns 1 if we reached EOF, 0 otherwise
int ps_err ( Pcpstream stream)

Check if an error occurred during a read or write operation.

Parameters
[in]streamThe stream object.
Returns
Returns 1 if there were any errors or 0 otherwise. Also check errno() and fatals_ifany().
size_t ps_finish ( Pcpstream stream)

Finalize writing the stream.

You NEED to call this function after you're done writing to the stream if you enabled Z85 armoring using ps_armor().

It writes the remaining bytes (encoded) to the stream destination.

Parameters
[in]streamThe input stream to write to.
Returns
Returns the number of bytes written. in case of errors it returns 0.
Pcpstream* ps_new_file ( FILE *  backendfd)

Create a new stream, backed with an open file.

The stream used for in- or output.

Parameters
[in]backendfdAn open FILE stream.
Returns
Returns a Pcpstream structure.
Pcpstream* ps_new_inbuffer ( Buffer b)

Create a new input stream, backed with filled a buffer.

This kind of stream can be used for reading only.

Parameters
[in]bA Buffer object filled with data.
Returns
Returns a Pcpstream structure.
Pcpstream* ps_new_outbuffer ( )

Create a new output stream, backed with a buffer.

The buffer used to write data to will be allocated and filled by the class. You can retrieve it later.

Returns
Returns a Pcpstream structure.
size_t ps_print ( Pcpstream stream,
const char *  fmt,
  ... 
)

Write a formatted string to the stream.

Use an printf() style format string to print something out to a stream.

Sets err in case of an error. See ps_err().

Parameters
[out]streamThe input stream to read from.
[in]fmtThe printf() compatible format description.
[in]...A variable number of arguments for the format string.
Returns
Returns the number of bytes written. in case of errors it returns 0.
size_t ps_read ( Pcpstream stream,
void *  buf,
size_t  readbytes 
)

Read bytes into the given buffer from the current stream.

This function reads 'readbytes' bytes from the stream into given buf. The buffer needs to be properly allocated by the caller in advance to have at least readbytes len.

Sets eof=1 if end of file or end of buffer has been reached.

Sets err=1 if an error occurred, fatals() maybe set, or errno.

See ps_end() and ps_err().

Parameters
[in]streamThe input stream to read from.
[out]bufThe buffer where to put read bytes.
[in]readbytesThe number of bytes to read.
Returns
Returns the bytes read, if there's nothing more to read, it returns 0.
int ps_readline ( Pcpstream stream,
Buffer line 
)

Read a line from the stream.

Parameters
[in]streamThe stream object.
[out]lineLinecontent will be written to this Buffer.
Returns
Returns the number of bytes read or -1 if PSMAXLINE have been reached or the input doesn't have any newlines at all.
void ps_setdetermine ( Pcpstream stream,
size_t  blocksize 
)

Enable auto Z85 encoding detection for an input stream.

If you're not sure if your input is Z85 encoded, enable detection.

Parameters
[in]streamThe stream object.
[in]blocksizeThe blocksize to for Z85 decoding (if encoded).
size_t ps_tell ( Pcpstream stream)

Tell the current read or write offset.

This function works like ftell() on a FILE stream or like Buffer->offset in the Buffer class.

Parameters
[in]streamThe input stream to read from.
Returns
Returns the the number of bytes read/written so far.
void ps_unarmor ( Pcpstream stream)

Disable Z85 encoding for an output stream.

Parameters
[in]streamThe stream object.
size_t ps_write ( Pcpstream stream,
void *  buf,
size_t  writebytes 
)

Write bytes from the given buffer into the current stream.

This function writes 'writebytes' bytes from the given buf into the stream

Sets err in case of an error. See ps_err().

Parameters
[out]streamThe input stream to write to.
[in]bufThe buffer containing data to put into the stream.
[in]writebytesThe number of bytes to write.
Returns
Returns the number of bytes written. in case of errors it returns 0.