1843e198johnlev/*
2843e198johnlev * CDDL HEADER START
3843e198johnlev *
4843e198johnlev * The contents of this file are subject to the terms of the
5843e198johnlev * Common Development and Distribution License (the "License").
6843e198johnlev * You may not use this file except in compliance with the License.
7843e198johnlev *
8843e198johnlev * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9843e198johnlev * or http://www.opensolaris.org/os/licensing.
10843e198johnlev * See the License for the specific language governing permissions
11843e198johnlev * and limitations under the License.
12843e198johnlev *
13843e198johnlev * When distributing Covered Code, include this CDDL HEADER in each
14843e198johnlev * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15843e198johnlev * If applicable, add the following below this CDDL HEADER, with the
16843e198johnlev * fields enclosed by brackets "[]" replaced with your own identifying
17843e198johnlev * information: Portions Copyright [yyyy] [name of copyright owner]
18843e198johnlev *
19843e198johnlev * CDDL HEADER END
20843e198johnlev */
21843e198johnlev/*
22843e198johnlev * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23843e198johnlev * Use is subject to license terms.
24843e198johnlev */
25843e198johnlev
26843e198johnlev#pragma ident	"%Z%%M%	%I%	%E% SMI"
27843e198johnlev
28843e198johnlev/*
29843e198johnlev * Memory I/O backend.
30843e198johnlev *
31843e198johnlev * Simple backend that has main memory as its backing store.
32843e198johnlev */
33843e198johnlev
34843e198johnlev#include <mdb/mdb_io_impl.h>
35843e198johnlev#include <mdb/mdb.h>
36843e198johnlev
37843e198johnlevtypedef struct mem_data {
38843e198johnlev	char *md_buf;
39843e198johnlev	size_t md_size;
40843e198johnlev	offset_t md_off;
41843e198johnlev} mem_data_t;
42843e198johnlev
43843e198johnlevstatic ssize_t
44843e198johnlevmemio_read(mdb_io_t *io, void *buf, size_t nbytes)
45843e198johnlev{
46843e198johnlev	mem_data_t *mdp = io->io_data;
47843e198johnlev
48843e198johnlev	if (io->io_next == NULL) {
49843e198johnlev		if (mdp->md_off + nbytes > mdp->md_size)
50843e198johnlev			nbytes = (mdp->md_size - mdp->md_off);
51843e198johnlev		bcopy(mdp->md_buf + mdp->md_off, buf, nbytes);
52843e198johnlev		mdp->md_off += nbytes;
53843e198johnlev		return (nbytes);
54843e198johnlev	}
55843e198johnlev
56843e198johnlev	return (IOP_READ(io->io_next, buf, nbytes));
57843e198johnlev}
58843e198johnlev
59843e198johnlevstatic off64_t
60843e198johnlevmemio_seek(mdb_io_t *io, off64_t offset, int whence)
61843e198johnlev{
62843e198johnlev	mem_data_t *mdp = io->io_data;
63843e198johnlev
64843e198johnlev	if (io->io_next == NULL) {
65843e198johnlev		switch (whence) {
66843e198johnlev		case SEEK_SET:
67843e198johnlev			mdp->md_off = offset;
68843e198johnlev			break;
69843e198johnlev		case SEEK_CUR:
70843e198johnlev			mdp->md_off += offset;
71843e198johnlev			break;
72843e198johnlev		case SEEK_END:
73843e198johnlev			mdp->md_off = mdp->md_size + offset;
74843e198johnlev			if (mdp->md_off > mdp->md_size)
75843e198johnlev				mdp->md_off = mdp->md_size;
76843e198johnlev			break;
77843e198johnlev		default:
78843e198johnlev			return (-1);
79843e198johnlev		}
80843e198johnlev
81843e198johnlev		return (mdp->md_off);
82843e198johnlev	}
83843e198johnlev
84843e198johnlev	return (IOP_SEEK(io->io_next, offset, whence));
85843e198johnlev}
86843e198johnlev
87843e198johnlevstatic const mdb_io_ops_t memio_ops = {
88843e198johnlev	memio_read,
89843e198johnlev	no_io_write,
90843e198johnlev	memio_seek,
91843e198johnlev	no_io_ctl,
92843e198johnlev	no_io_close,
93843e198johnlev	no_io_name,
94843e198johnlev	no_io_link,
95843e198johnlev	no_io_unlink,
96843e198johnlev	no_io_setattr,
97843e198johnlev	no_io_suspend,
98843e198johnlev	no_io_resume
99843e198johnlev};
100843e198johnlev
101843e198johnlevmdb_io_t *
102843e198johnlevmdb_memio_create(char *buf, size_t size)
103843e198johnlev{
104843e198johnlev	mdb_io_t *io = mdb_alloc(sizeof (mdb_io_t), UM_SLEEP);
105843e198johnlev	mem_data_t *mdp = mdb_alloc(sizeof (mem_data_t), UM_SLEEP);
106843e198johnlev
107843e198johnlev	mdp->md_buf = buf;
108843e198johnlev	mdp->md_size = size;
109843e198johnlev	mdp->md_off = 0;
110843e198johnlev
111843e198johnlev	io->io_ops = &memio_ops;
112843e198johnlev	io->io_data = mdp;
113843e198johnlev	io->io_next = NULL;
114843e198johnlev	io->io_refcnt = 0;
115843e198johnlev
116843e198johnlev	return (io);
117843e198johnlev}
118