1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#pragma ident	"%Z%%M%	%I%	%E% SMI"
28
29#include "streams_array.h"
30#include "streams_common.h"
31
32/*
33 * Single-byte character memory map-based streams implementation
34 */
35
36static int
37stream_array_prime(stream_t *str)
38{
39	ASSERT((str->s_status & STREAM_SOURCE_MASK) == STREAM_ARRAY);
40
41	str->s_type.LA.s_cur_index = MIN(0, str->s_type.LA.s_array_size - 1);
42	if (str->s_type.LA.s_cur_index >= 0)
43		copy_line_rec(
44		    str->s_type.LA.s_array[str->s_type.LA.s_cur_index],
45		    &str->s_current);
46	else {
47		stream_set(str, STREAM_EOS_REACHED);
48		stream_unset(str, STREAM_PRIMED);
49		return (PRIME_FAILED_EMPTY_FILE);
50	}
51
52	stream_set(str, STREAM_PRIMED);
53
54	return (PRIME_SUCCEEDED);
55}
56
57static ssize_t
58stream_array_fetch(stream_t *str)
59{
60	ASSERT(str->s_status & STREAM_OPEN);
61	ASSERT(str->s_type.LA.s_cur_index < str->s_type.LA.s_array_size);
62
63	if (++str->s_type.LA.s_cur_index == str->s_type.LA.s_array_size - 1)
64		stream_set(str, STREAM_EOS_REACHED);
65
66	copy_line_rec(str->s_type.LA.s_array[str->s_type.LA.s_cur_index],
67	    &str->s_current);
68
69	return (NEXT_LINE_COMPLETE);
70}
71
72/*ARGSUSED*/
73static int
74stream_array_is_closable(stream_t *str)
75{
76	/*
77	 * Array streams are not closable.  That is, there is no open file
78	 * descriptor directly associated with an array stream.
79	 */
80	return (0);
81}
82
83static int
84stream_array_close(stream_t *str)
85{
86	stream_unset(str, STREAM_OPEN | STREAM_PRIMED);
87
88	return (1);
89}
90
91static int
92stream_array_free(stream_t *str)
93{
94	/*
95	 * It's now safe for us to close the various streams backing the array
96	 * stream's data.
97	 */
98	stream_unset(str, STREAM_PRIMED | STREAM_NOT_FREEABLE);
99
100	return (1);
101}
102
103static int
104stream_array_eos(stream_t *str)
105{
106	int retval = 0;
107
108	if (str == NULL || str->s_status & STREAM_EOS_REACHED)
109		return (1);
110
111	if (str->s_type.LA.s_cur_index + 1 >= str->s_type.LA.s_array_size) {
112		retval = 1;
113		stream_set(str, STREAM_EOS_REACHED);
114	}
115
116	return (retval);
117}
118
119/*ARGSUSED*/
120static void
121stream_array_release_line(stream_t *str)
122{
123}
124
125const stream_ops_t stream_array_ops = {
126	stream_array_is_closable,
127	stream_array_close,
128	stream_array_eos,
129	stream_array_fetch,
130	NULL,
131	stream_array_free,
132	NULL,
133	stream_array_prime,
134	NULL,
135	stream_array_release_line,
136	NULL,
137	NULL
138};
139