147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/* 247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * Copyright 2004 The WebRTC Project Authors. All rights reserved. 347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * 447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * Use of this source code is governed by a BSD-style license 547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * that can be found in the LICENSE file in the root of the source 647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * tree. An additional intellectual property rights grant can be found 747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * in the file PATENTS. All contributing project authors may 847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * be found in the AUTHORS file in the root of the source tree. 947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org */ 1047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/transformadapter.h" 1247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <string.h> 1447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/common.h" 1647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgnamespace rtc { 1847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/////////////////////////////////////////////////////////////////////////////// 2047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 2147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgTransformAdapter::TransformAdapter(StreamInterface * stream, 2247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org TransformInterface * transform, 2347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool direction_read) 2447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org : StreamAdapterInterface(stream), transform_(transform), 2547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org direction_read_(direction_read), state_(ST_PROCESSING), len_(0) { 2647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 2747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 2847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgTransformAdapter::~TransformAdapter() { 2947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org TransformAdapter::Close(); 3047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org delete transform_; 3147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 3247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 3347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult 3447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgTransformAdapter::Read(void * buffer, size_t buffer_len, 3547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org size_t * read, int * error) { 3647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!direction_read_) 3747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return SR_EOS; 3847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 3947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org while (state_ != ST_ERROR) { 4047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (state_ == ST_COMPLETE) 4147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return SR_EOS; 4247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 4347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Buffer more data 4447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if ((state_ == ST_PROCESSING) && (len_ < sizeof(buffer_))) { 4547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org size_t subread; 4647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org StreamResult result = StreamAdapterInterface::Read( 4747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org buffer_ + len_, 4847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org sizeof(buffer_) - len_, 4947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org &subread, 5047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org &error_); 5147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (result == SR_BLOCK) { 5247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return SR_BLOCK; 5347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (result == SR_ERROR) { 5447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org state_ = ST_ERROR; 5547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 5647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (result == SR_EOS) { 5747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org state_ = ST_FLUSHING; 5847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 5947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org len_ += subread; 6047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 6147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 6247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 6347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Process buffered data 6447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org size_t in_len = len_; 6547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org size_t out_len = buffer_len; 6647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org StreamResult result = transform_->Transform(buffer_, &in_len, 6747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org buffer, &out_len, 6847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org (state_ == ST_FLUSHING)); 6947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASSERT(result != SR_BLOCK); 7047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (result == SR_EOS) { 7147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Note: Don't signal SR_EOS this iteration, unless out_len is zero 7247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org state_ = ST_COMPLETE; 7347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (result == SR_ERROR) { 7447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org state_ = ST_ERROR; 7547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org error_ = -1; // TODO: propagate error 7647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 7747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if ((out_len == 0) && (state_ == ST_FLUSHING)) { 7847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // If there is no output AND no more input, then something is wrong 7947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org state_ = ST_ERROR; 8047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org error_ = -1; // TODO: better error code? 8147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 8247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 8347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 8447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org len_ -= in_len; 8547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (len_ > 0) 8647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org memmove(buffer_, buffer_ + in_len, len_); 8747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 8847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (out_len == 0) 8947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org continue; 9047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 9147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (read) 9247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *read = out_len; 9347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return SR_SUCCESS; 9447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 9547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 9647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (error) 9747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *error = error_; 9847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return SR_ERROR; 9947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 10047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 10147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult 10247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgTransformAdapter::Write(const void * data, size_t data_len, 10347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org size_t * written, int * error) { 10447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (direction_read_) 10547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return SR_EOS; 10647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 10747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org size_t bytes_written = 0; 10847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org while (state_ != ST_ERROR) { 10947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (state_ == ST_COMPLETE) 11047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return SR_EOS; 11147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 11247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (len_ < sizeof(buffer_)) { 11347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Process buffered data 11447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org size_t in_len = data_len; 11547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org size_t out_len = sizeof(buffer_) - len_; 11647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org StreamResult result = transform_->Transform(data, &in_len, 11747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org buffer_ + len_, &out_len, 11847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org (state_ == ST_FLUSHING)); 11947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 12047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASSERT(result != SR_BLOCK); 12147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (result == SR_EOS) { 12247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Note: Don't signal SR_EOS this iteration, unless no data written 12347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org state_ = ST_COMPLETE; 12447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (result == SR_ERROR) { 12547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASSERT(false); // When this happens, think about what should be done 12647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org state_ = ST_ERROR; 12747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org error_ = -1; // TODO: propagate error 12847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 12947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 13047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 13147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org len_ = out_len; 13247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bytes_written = in_len; 13347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 13447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 13547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org size_t pos = 0; 13647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org while (pos < len_) { 13747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org size_t subwritten; 13847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org StreamResult result = StreamAdapterInterface::Write(buffer_ + pos, 13947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org len_ - pos, 14047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org &subwritten, 14147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org &error_); 14247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (result == SR_BLOCK) { 14347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASSERT(false); // TODO: we should handle this 14447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return SR_BLOCK; 14547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (result == SR_ERROR) { 14647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org state_ = ST_ERROR; 14747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 14847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (result == SR_EOS) { 14947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org state_ = ST_COMPLETE; 15047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 15147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 15247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 15347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org pos += subwritten; 15447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 15547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 15647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org len_ -= pos; 15747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (len_ > 0) 15847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org memmove(buffer_, buffer_ + pos, len_); 15947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 16047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (bytes_written == 0) 16147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org continue; 16247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 16347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (written) 16447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *written = bytes_written; 16547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return SR_SUCCESS; 16647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 16747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 16847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (error) 16947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *error = error_; 17047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return SR_ERROR; 17147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 17247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 17347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid 17447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgTransformAdapter::Close() { 17547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!direction_read_ && (state_ == ST_PROCESSING)) { 17647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org state_ = ST_FLUSHING; 17747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org do { 17847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Write(0, 0, NULL, NULL); 17947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } while (state_ == ST_FLUSHING); 18047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 18147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org state_ = ST_COMPLETE; 18247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org StreamAdapterInterface::Close(); 18347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 18447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 18547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} // namespace rtc 186