xref: /illumos-gate/usr/src/cmd/sort/streams_array.c (revision 0cc97882c52f30e61739644e480f5f9f980b1621)
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 #include "streams_array.h"
28 #include "streams_common.h"
29 
30 /*
31  * Single-byte character memory map-based streams implementation
32  */
33 
34 static int
35 stream_array_prime(stream_t *str)
36 {
37 	ASSERT((str->s_status & STREAM_SOURCE_MASK) == STREAM_ARRAY);
38 
39 	str->s_type.LA.s_cur_index = MIN(0, str->s_type.LA.s_array_size - 1);
40 	if (str->s_type.LA.s_cur_index >= 0)
41 		copy_line_rec(
42 		    str->s_type.LA.s_array[str->s_type.LA.s_cur_index],
43 		    &str->s_current);
44 	else {
45 		stream_set(str, STREAM_EOS_REACHED);
46 		stream_unset(str, STREAM_PRIMED);
47 		return (PRIME_FAILED_EMPTY_FILE);
48 	}
49 
50 	stream_set(str, STREAM_PRIMED);
51 
52 	return (PRIME_SUCCEEDED);
53 }
54 
55 static ssize_t
56 stream_array_fetch(stream_t *str)
57 {
58 	ASSERT(str->s_status & STREAM_OPEN);
59 	ASSERT(str->s_type.LA.s_cur_index < str->s_type.LA.s_array_size);
60 
61 	if (++str->s_type.LA.s_cur_index == str->s_type.LA.s_array_size - 1)
62 		stream_set(str, STREAM_EOS_REACHED);
63 
64 	copy_line_rec(str->s_type.LA.s_array[str->s_type.LA.s_cur_index],
65 	    &str->s_current);
66 
67 	return (NEXT_LINE_COMPLETE);
68 }
69 
70 /*ARGSUSED*/
71 static int
72 stream_array_is_closable(stream_t *str)
73 {
74 	/*
75 	 * Array streams are not closable.  That is, there is no open file
76 	 * descriptor directly associated with an array stream.
77 	 */
78 	return (0);
79 }
80 
81 static int
82 stream_array_close(stream_t *str)
83 {
84 	stream_unset(str, STREAM_OPEN | STREAM_PRIMED);
85 
86 	return (1);
87 }
88 
89 static int
90 stream_array_free(stream_t *str)
91 {
92 	/*
93 	 * It's now safe for us to close the various streams backing the array
94 	 * stream's data.
95 	 */
96 	stream_unset(str, STREAM_PRIMED | STREAM_NOT_FREEABLE);
97 
98 	return (1);
99 }
100 
101 static int
102 stream_array_eos(stream_t *str)
103 {
104 	int retval = 0;
105 
106 	if (str == NULL || str->s_status & STREAM_EOS_REACHED)
107 		return (1);
108 
109 	if (str->s_type.LA.s_cur_index + 1 >= str->s_type.LA.s_array_size) {
110 		retval = 1;
111 		stream_set(str, STREAM_EOS_REACHED);
112 	}
113 
114 	return (retval);
115 }
116 
117 /*ARGSUSED*/
118 static void
119 stream_array_release_line(stream_t *str)
120 {
121 }
122 
123 const stream_ops_t stream_array_ops = {
124 	stream_array_is_closable,
125 	stream_array_close,
126 	stream_array_eos,
127 	stream_array_fetch,
128 	NULL,
129 	stream_array_free,
130 	NULL,
131 	stream_array_prime,
132 	NULL,
133 	stream_array_release_line,
134 	NULL,
135 	NULL
136 };
137