~timkross/cjdns/cjdns

« back to all changes in this revision

Viewing changes to io/ArrayWriter.c

  • Committer: cjdelisle
  • Date: 2011-02-16 23:03:00 UTC
  • Revision ID: git-v1:d475c9c10adc25590bea5e7dc5383b32f66d5eb8
First commit for cjdns.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "ArrayWriter.h"
 
2
#include <string.h>
 
3
 
 
4
struct ArrayWriter_context {
 
5
    char* beginPointer;
 
6
    char* pointer;
 
7
    char* endPointer;
 
8
    int returnCode;
 
9
};
 
10
 
 
11
static int write(void* toWrite, size_t length, struct Writer* writer);
 
12
static uint64_t bytesWritten(struct Writer* writer);
 
13
 
 
14
/** @see ArrayWriter.h */
 
15
struct Writer* ArrayWriter_new(void* writeToBuffer,
 
16
                               size_t length,
 
17
                               struct MemAllocator* allocator)
 
18
{
 
19
    struct Writer* writer =
 
20
        allocator->calloc(sizeof(struct Writer), 1, allocator);
 
21
    struct ArrayWriter_context* context =
 
22
        allocator->calloc(sizeof(struct ArrayWriter_context), 1, allocator);
 
23
 
 
24
    if (context == NULL || writer == NULL) {
 
25
        return NULL;
 
26
    }
 
27
 
 
28
    context->beginPointer = (char*) writeToBuffer;
 
29
    context->pointer = (char*) writeToBuffer;
 
30
    context->endPointer = (char*) writeToBuffer + length;
 
31
 
 
32
    struct Writer localWriter = {
 
33
        .context = context,
 
34
        .write = write,
 
35
        .bytesWritten = bytesWritten
 
36
    };
 
37
    memcpy(writer, &localWriter, sizeof(struct Writer));
 
38
 
 
39
    return writer;
 
40
}
 
41
 
 
42
/** @see Writer->write() */
 
43
static int write(void* toWrite, size_t length, struct Writer* writer)
 
44
{
 
45
    struct ArrayWriter_context* context =
 
46
        (struct ArrayWriter_context*) writer->context;
 
47
 
 
48
    /* If there was a previous failure then don't allow any more writing. */
 
49
    if (context->returnCode != 0) {
 
50
        return context->returnCode;
 
51
    }
 
52
 
 
53
    /* Prove that it doesn't run off the end of the buffer or roll over. */
 
54
    if (context->pointer + length >= context->endPointer
 
55
        || context->pointer + length < context->pointer)
 
56
    {
 
57
        context->returnCode = -1;
 
58
        return -1;
 
59
    }
 
60
 
 
61
    memcpy(context->pointer, toWrite, length);
 
62
    context->pointer += length;
 
63
 
 
64
    return 0;
 
65
}
 
66
 
 
67
static uint64_t bytesWritten(struct Writer* writer)
 
68
{
 
69
    struct ArrayWriter_context* context =
 
70
        (struct ArrayWriter_context*) writer->context;
 
71
 
 
72
    return context->pointer - context->beginPointer;
 
73
}