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 (c) 1990-2001 by Sun Microsystems, Inc.
24 * All rights reserved.
25 */
26
27#pragma ident	"%Z%%M%	%I%	%E% SMI"
28
29#include <stdlib.h>
30#include <unistd.h>
31#include <AudioPipe.h>
32
33// class AudioPipe methods
34
35
36// Constructor with file descriptor, mode, and optional name
37AudioPipe::
38AudioPipe(
39	const int		desc,		// file descriptor
40	const FileAccess	acc,		// access mode
41	const char		*name_local):	// name
42	AudioUnixfile(name_local, acc)
43{
44	setfd(desc);
45}
46
47// The create routine for pipes writes a file header
48AudioError AudioPipe::
49Create()
50{
51	AudioError	err;
52
53	// Was the header properly set?
54	err = GetHeader().Validate();
55	if (err != AUDIO_SUCCESS)
56		return (RaiseError(err));
57
58	// Open fd supplied by constructor
59	if (!isfdset())
60		return (RaiseError(AUDIO_ERR_NOEFFECT));
61
62	// Write the file header with current (usually unknown) size
63	err = encode_filehdr();
64	if (err != AUDIO_SUCCESS) {
65		(void) close(getfd());		// If error, remove file
66		setfd(-1);
67		return (err);
68	}
69
70	// Set the actual output length to zero
71	setlength(0.);
72
73	return (AUDIO_SUCCESS);
74}
75
76// The open routine for pipes decodes the header
77AudioError AudioPipe::
78Open()
79{
80	AudioError		err;
81
82	// The constructor should have supplied a valid fd
83	if (!isfdset())
84		return (RaiseError(AUDIO_ERR_NOEFFECT));
85
86	// Decode a file header
87	err = decode_filehdr();
88	if (err != AUDIO_SUCCESS) {
89		(void) close(getfd());
90		setfd(-1);
91		return (err);
92	}
93
94	return (AUDIO_SUCCESS);
95}
96
97// Read data from underlying pipe into specified buffer.
98// No data format translation takes place.
99// Since there's no going back, the object's read position pointer is updated.
100AudioError AudioPipe::
101ReadData(
102	void*		buf,		// destination buffer address
103	size_t&		len,		// buffer length (updated)
104	Double&		pos)		// start position (updated)
105{
106	AudioError	err;
107	char		*tbuf;		// current buffer pointer
108	size_t		remain;		// number of bytes remaining
109	size_t		cnt;		// accumulated number of bytes read
110
111	tbuf = (char *)buf;
112	remain = len;
113	cnt = 0;
114
115	// Pipes return short reads.  If non-blocking i/o, try to read all.
116	do {
117		// Call the real routine
118		err = AudioUnixfile::ReadData((void*)tbuf, remain, pos);
119
120		// Update the object's read position
121		if (!err) {
122			(void) SetReadPosition(pos, Absolute);
123			if (remain == 0)
124				break;
125			cnt += remain;
126			tbuf += remain;
127			remain = len - cnt;
128		}
129	} while (!err && (remain > 0) && GetBlocking());
130	len = cnt;
131	if (len > 0)
132		return (AUDIO_SUCCESS);
133	return (err);
134}
135
136// Write data to underlying file from specified buffer.
137// No data format translation takes place.
138// Since there's no going back, the object's write position pointer is updated.
139AudioError AudioPipe::
140WriteData(
141	void*		buf,		// source buffer address
142	size_t&		len,		// buffer length (updated)
143	Double&		pos)		// start position (updated)
144{
145	AudioError	err;
146
147	// Call the real routine
148	err = AudioUnixfile::WriteData(buf, len, pos);
149
150	// Update the object's write position
151	if (err == AUDIO_SUCCESS)
152		(void) SetWritePosition(pos, Absolute);
153	return (err);
154}
155