Search
lxdream.org :: lxdream/src/drivers/cdrom/isomem.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/drivers/cdrom/isomem.c
changeset 1227:cf6126df0398
prev1179:af1c5d7d5a5a
author nkeynes
date Thu Feb 23 14:59:58 2012 +1000 (8 years ago)
permissions -rw-r--r--
last change mem_stream_class should be static (to avoid potential conflicts with the
real one)
file annotate diff log raw
nkeynes@1152
     1
/*
nkeynes@1152
     2
 * Copyright (c) 2007 Vreixo Formoso
nkeynes@1152
     3
 * Copyright (c) 2009 Thomas Schmitt
nkeynes@1152
     4
 *
nkeynes@1152
     5
 * This file is part of the libisofs project; you can redistribute it and/or
nkeynes@1152
     6
 * modify it under the terms of the GNU General Public License version 2 
nkeynes@1152
     7
 * or later as published by the Free Software Foundation. 
nkeynes@1152
     8
 * See COPYING file for details.
nkeynes@1152
     9
 *
nkeynes@1152
    10
 * Memory stream extracted for use in lxdream by Nathan Keynes 2010.
nkeynes@1152
    11
 */
nkeynes@1152
    12
nkeynes@1152
    13
nkeynes@1152
    14
#include <stdlib.h>
nkeynes@1152
    15
#include <string.h>
nkeynes@1152
    16
#include <limits.h>
nkeynes@1152
    17
#include <stdio.h>
nkeynes@1179
    18
#include <stdint.h>
nkeynes@1179
    19
#include <libisofs.h>
nkeynes@1179
    20
nkeynes@1152
    21
nkeynes@1152
    22
#ifndef MIN
nkeynes@1152
    23
#define MIN(a,b) ((a)<=(b) ? (a) : (b))
nkeynes@1152
    24
#endif
nkeynes@1152
    25
nkeynes@1152
    26
#define ISO_MEM_FS_ID 4
nkeynes@1152
    27
nkeynes@1158
    28
static ino_t mem_serial_id = (ino_t)1;
nkeynes@1152
    29
nkeynes@1152
    30
typedef struct
nkeynes@1152
    31
{
nkeynes@1152
    32
    uint8_t *buf;
nkeynes@1152
    33
    ssize_t offset; /* -1 if stream closed */
nkeynes@1152
    34
    ino_t ino_id;
nkeynes@1152
    35
    size_t size;
nkeynes@1152
    36
} MemStreamData;
nkeynes@1152
    37
nkeynes@1152
    38
static
nkeynes@1152
    39
int mem_open(IsoStream *stream)
nkeynes@1152
    40
{
nkeynes@1152
    41
    MemStreamData *data;
nkeynes@1152
    42
    if (stream == NULL) {
nkeynes@1152
    43
        return ISO_NULL_POINTER;
nkeynes@1152
    44
    }
nkeynes@1152
    45
    data = (MemStreamData*)stream->data;
nkeynes@1152
    46
    if (data->offset != -1) {
nkeynes@1152
    47
        return ISO_FILE_ALREADY_OPENED;
nkeynes@1152
    48
    }
nkeynes@1152
    49
    data->offset = 0;
nkeynes@1152
    50
    return ISO_SUCCESS;
nkeynes@1152
    51
}
nkeynes@1152
    52
nkeynes@1152
    53
static
nkeynes@1152
    54
int mem_close(IsoStream *stream)
nkeynes@1152
    55
{
nkeynes@1152
    56
    MemStreamData *data;
nkeynes@1152
    57
    if (stream == NULL) {
nkeynes@1152
    58
        return ISO_NULL_POINTER;
nkeynes@1152
    59
    }
nkeynes@1152
    60
    data = (MemStreamData*)stream->data;
nkeynes@1152
    61
    if (data->offset == -1) {
nkeynes@1152
    62
        return ISO_FILE_NOT_OPENED;
nkeynes@1152
    63
    }
nkeynes@1152
    64
    data->offset = -1;
nkeynes@1152
    65
    return ISO_SUCCESS;
nkeynes@1152
    66
}
nkeynes@1152
    67
nkeynes@1152
    68
static
nkeynes@1152
    69
off_t mem_get_size(IsoStream *stream)
nkeynes@1152
    70
{
nkeynes@1152
    71
    MemStreamData *data;
nkeynes@1152
    72
    data = (MemStreamData*)stream->data;
nkeynes@1152
    73
nkeynes@1152
    74
    return (off_t)data->size;
nkeynes@1152
    75
}
nkeynes@1152
    76
nkeynes@1152
    77
static
nkeynes@1152
    78
int mem_read(IsoStream *stream, void *buf, size_t count)
nkeynes@1152
    79
{
nkeynes@1152
    80
    size_t len;
nkeynes@1152
    81
    MemStreamData *data;
nkeynes@1152
    82
    if (stream == NULL || buf == NULL) {
nkeynes@1152
    83
        return ISO_NULL_POINTER;
nkeynes@1152
    84
    }
nkeynes@1152
    85
    if (count == 0) {
nkeynes@1152
    86
        return ISO_WRONG_ARG_VALUE;
nkeynes@1152
    87
    }
nkeynes@1152
    88
    data = stream->data;
nkeynes@1152
    89
nkeynes@1152
    90
    if (data->offset == -1) {
nkeynes@1152
    91
        return ISO_FILE_NOT_OPENED;
nkeynes@1152
    92
    }
nkeynes@1152
    93
nkeynes@1152
    94
    if (data->offset >= data->size) {
nkeynes@1152
    95
        return 0; /* EOF */
nkeynes@1152
    96
    }
nkeynes@1152
    97
nkeynes@1152
    98
    len = MIN(count, data->size - data->offset);
nkeynes@1152
    99
    memcpy(buf, data->buf + data->offset, len);
nkeynes@1152
   100
    data->offset += len;
nkeynes@1152
   101
    return len;
nkeynes@1152
   102
}
nkeynes@1152
   103
nkeynes@1152
   104
static
nkeynes@1152
   105
int mem_is_repeatable(IsoStream *stream)
nkeynes@1152
   106
{
nkeynes@1152
   107
    return 1;
nkeynes@1152
   108
}
nkeynes@1152
   109
nkeynes@1152
   110
static
nkeynes@1152
   111
void mem_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id,
nkeynes@1152
   112
                ino_t *ino_id)
nkeynes@1152
   113
{
nkeynes@1152
   114
    MemStreamData *data;
nkeynes@1152
   115
    data = (MemStreamData*)stream->data;
nkeynes@1152
   116
    *fs_id = ISO_MEM_FS_ID;
nkeynes@1152
   117
    *dev_id = 0;
nkeynes@1152
   118
    *ino_id = data->ino_id;
nkeynes@1152
   119
}
nkeynes@1152
   120
nkeynes@1152
   121
static
nkeynes@1152
   122
void mem_free(IsoStream *stream)
nkeynes@1152
   123
{
nkeynes@1152
   124
    MemStreamData *data;
nkeynes@1152
   125
    data = (MemStreamData*)stream->data;
nkeynes@1152
   126
    free(data->buf);
nkeynes@1152
   127
    free(data);
nkeynes@1152
   128
}
nkeynes@1152
   129
nkeynes@1227
   130
static IsoStreamIface mem_stream_class = {
nkeynes@1152
   131
    0,
nkeynes@1152
   132
    "mem ",
nkeynes@1152
   133
    mem_open,
nkeynes@1152
   134
    mem_close,
nkeynes@1152
   135
    mem_get_size,
nkeynes@1152
   136
    mem_read,
nkeynes@1152
   137
    mem_is_repeatable,
nkeynes@1152
   138
    mem_get_id,
nkeynes@1152
   139
    mem_free
nkeynes@1152
   140
};
nkeynes@1152
   141
nkeynes@1152
   142
/**
nkeynes@1152
   143
 * Create a stream for reading from a arbitrary memory buffer.
nkeynes@1152
   144
 * When the Stream refcount reach 0, the buffer is free(3).
nkeynes@1152
   145
 *
nkeynes@1152
   146
 * @return
nkeynes@1152
   147
 *      1 sucess, < 0 error
nkeynes@1152
   148
 */
nkeynes@1152
   149
int iso_mem_stream_new(unsigned char *buf, size_t size, IsoStream **stream)
nkeynes@1152
   150
{
nkeynes@1152
   151
    IsoStream *str;
nkeynes@1152
   152
    MemStreamData *data;
nkeynes@1152
   153
nkeynes@1152
   154
    if (buf == NULL || stream == NULL) {
nkeynes@1152
   155
        return ISO_NULL_POINTER;
nkeynes@1152
   156
    }
nkeynes@1152
   157
nkeynes@1152
   158
    str = malloc(sizeof(IsoStream));
nkeynes@1152
   159
    if (str == NULL) {
nkeynes@1152
   160
        return ISO_OUT_OF_MEM;
nkeynes@1152
   161
    }
nkeynes@1152
   162
    data = malloc(sizeof(MemStreamData));
nkeynes@1152
   163
    if (data == NULL) {
nkeynes@1152
   164
        free(str);
nkeynes@1152
   165
        return ISO_OUT_OF_MEM;
nkeynes@1152
   166
    }
nkeynes@1152
   167
nkeynes@1152
   168
    /* fill data */
nkeynes@1152
   169
    data->buf = buf;
nkeynes@1152
   170
    data->size = size;
nkeynes@1152
   171
    data->offset = -1;
nkeynes@1152
   172
    data->ino_id = mem_serial_id++;
nkeynes@1152
   173
nkeynes@1152
   174
    str->refcount = 1;
nkeynes@1152
   175
    str->data = data;
nkeynes@1152
   176
    str->class = &mem_stream_class;
nkeynes@1152
   177
nkeynes@1152
   178
    *stream = str;
nkeynes@1152
   179
    return ISO_SUCCESS;
nkeynes@1152
   180
}
.