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::
AudioPipe(const int desc,const FileAccess acc,const char * name_local)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::
Create()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::
Open()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::
ReadData(void * buf,size_t & len,Double & pos)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::
WriteData(void * buf,size_t & len,Double & pos)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