|
4 | 4 | """
|
5 | 5 | An abstract codec type.
|
6 | 6 |
|
7 |
| -Any codec supporting transcoding interfaces must be a subtype of this type. |
| 7 | +Any codec supporting the transcoding protocol must be a subtype of this type. |
| 8 | +
|
| 9 | +
|
| 10 | +Transcoding protocol |
| 11 | +-------------------- |
| 12 | +
|
| 13 | +Transcoding proceeds by calling some functions in a specific way. We call this |
| 14 | +"transcoding protocol" and any codec must implement it as described below. |
| 15 | +
|
| 16 | +There are four functions for a codec to implement: |
| 17 | +- initialize: initialize the codec |
| 18 | +- finalize: finalize the codec |
| 19 | +- startproc: start processing with the codec |
| 20 | +- process: process data with the codec. |
| 21 | +
|
| 22 | +These are defined in the `TranscodingStreams` and a new codec type must extend |
| 23 | +these methods if necessary. Implementing a `process` method is mandatory but |
| 24 | +other three are optional. `initialize`, `finalize`, and `startproc` have a |
| 25 | +default implementation that does nothing. |
| 26 | +
|
| 27 | +Your codec type is denoted by `C` and its object by `codec`. |
| 28 | +
|
| 29 | +The `initialize(codec::C)::Void` method takes `codec` and returns |
| 30 | +`nothing`. This is called once and only once before starting any data |
| 31 | +processing. Therefore, you may initialize `codec` (e.g. allocating memory |
| 32 | +needed to process data) with this method. If initialization fails for some |
| 33 | +reason, it may throw an exception and no other methods will be called. |
| 34 | +
|
| 35 | +The `finalize(codec::C)::Void` method takes `codec` and returns `nothing`. This |
| 36 | +is called when and only when the transcoding stream goes to the close state |
| 37 | +(i.e. when `Base.close` is called). Therefore, you may finalize `codec` (e.g. |
| 38 | +freeing memory) with this method. If finalization fails for some reason, it may |
| 39 | +throw an exception. Even when an exception is thrown while finalizing a stream, |
| 40 | +the stream will become the close state for safety. |
| 41 | +
|
| 42 | +The `startproc(codec::C, state::Symbol)::Symbol` method takes `codec` and |
| 43 | +`state`, and returns a status code. This is called just before the stream starts |
| 44 | +reading or writing data. `state` is either `:read` or `:write` and then the |
| 45 | +stream starts reading or writing, respectively. The return code must be `:ok` if |
| 46 | +`codec` is ready to read or write data. Otherwise, it should be `:fail` and then |
| 47 | +the stream throws an exception. |
| 48 | +
|
| 49 | +The `process(codec::C, input::Memory, output::Memory)::Tuple{Int,Int,Symbol}` |
| 50 | +method takes `codec`, `input` and `output`, and returns a consumed data size, a |
| 51 | +produced data size and a status code. This is called repeatedly while processing |
| 52 | +data. The input (`input`) and output (`output`) data are a `Memory` object, |
| 53 | +which is a pointer to a contiguous memory region with size. You must read input |
| 54 | +data from `input`, transcode the bytes, and then write the output data to |
| 55 | +`output`. Finally you need to return the size of read data, the size of written |
| 56 | +data, and `:ok` status code so that the caller can know how many bytes are |
| 57 | +consumed and produced in the method. When transcoding reaches the end of a data |
| 58 | +stream, it is notified to this method by empty input. In that case, the method |
| 59 | +need to write the buffered data (if any) to `output`. If there is no data to |
| 60 | +write, the status code must be set to `:end`. The `process` method will be |
| 61 | +called repeatedly until it returns `:end` status code. |
| 62 | +
|
8 | 63 | """
|
9 | 64 | abstract type Codec end
|
10 | 65 |
|
|
0 commit comments