xref: /illumos-gate/usr/src/cmd/audio/utilities/AudioPipe.cc (revision 581cede61ac9c14d8d4ea452562a567189eead78)
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
37 AudioPipe::
38 AudioPipe(
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
48 AudioError AudioPipe::
49 Create()
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
77 AudioError AudioPipe::
78 Open()
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.
100 AudioError AudioPipe::
101 ReadData(
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.
139 AudioError AudioPipe::
140 WriteData(
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