1 /*
2  * This source file is part of libRocket, the HTML/CSS Interface Middleware
3  *
4  * For the latest information, see http://www.librocket.com
5  *
6  * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24  * THE SOFTWARE.
25  *
26  */
27 
28 #include "precompiled.h"
29 #include "../../Include/Rocket/Core/Stream.h"
30 #include <algorithm>
31 #include <stdio.h>
32 
33 namespace Rocket {
34 namespace Core {
35 
36 const size_t READ_BLOCK_SIZE = 1024;
37 
Stream()38 Stream::Stream() : ReferenceCountable(1)
39 {
40 	stream_mode = 0;
41 }
42 
~Stream()43 Stream::~Stream()
44 {
45 }
46 
Close()47 void Stream::Close()
48 {
49 	stream_mode = 0;
50 }
51 
52 // Returns the mode the stream was opened in.
GetStreamMode() const53 int Stream::GetStreamMode() const
54 {
55 	return stream_mode;
56 }
57 
58 // Returns the source url (if available)
GetSourceURL() const59 const URL& Stream::GetSourceURL() const
60 {
61 	return url;
62 }
63 
IsEOS() const64 bool Stream::IsEOS() const
65 {
66 	return Tell() >= Length();
67 }
68 
Peek(void * buffer,size_t bytes) const69 size_t Stream::Peek(void* buffer, size_t bytes) const
70 {
71 	size_t pos = Tell();
72 	size_t read = Read( buffer, bytes );
73 	Seek( (long)pos, SEEK_SET );
74 	return read;
75 }
76 
77 // Read from one stream into another
Read(Stream * stream,size_t bytes) const78 size_t Stream::Read(Stream* stream, size_t bytes) const
79 {
80 	byte buffer[ READ_BLOCK_SIZE ];
81 	size_t total_bytes_read = 0;
82 	while (total_bytes_read < bytes)
83 	{
84 		size_t bytes_read = this->Read(buffer, Core::Math::Min(READ_BLOCK_SIZE, bytes - total_bytes_read));
85 		if (bytes_read < 1)
86 			return total_bytes_read;
87 		stream->Write(buffer, bytes_read);
88 		total_bytes_read += bytes_read;
89 	}
90 	return total_bytes_read;
91 }
92 
93 // Read from one stream into another
Read(String & string,size_t bytes) const94 size_t Stream::Read(String& string, size_t bytes) const
95 {
96 	size_t string_size = string.Length();
97 	string.Resize(string_size + bytes + 1);
98 	size_t read = Read(&string[string_size], bytes);
99 	string[string_size + read] = '\0';
100 	string.Resize(string_size + read);
101 	return read;
102 }
103 
104 /// Write to this stream from another stream
Write(const Stream * stream,size_t bytes)105 size_t Stream::Write(const Stream* stream, size_t bytes)
106 {
107 	return stream->Read(this, bytes);
108 }
109 
Write(const char * string)110 size_t Stream::Write(const char* string)
111 {
112 	return Write(string, strlen(string));
113 }
114 
Write(const String & string)115 size_t Stream::Write(const String& string)
116 {
117 	return Write(string.CString(), string.Length());
118 }
119 
120 // Push onto the front of the stream
PushFront(const void * ROCKET_UNUSED_PARAMETER (buffer),size_t ROCKET_UNUSED_PARAMETER (bytes))121 size_t Stream::PushFront(const void* ROCKET_UNUSED_PARAMETER(buffer), size_t ROCKET_UNUSED_PARAMETER(bytes))
122 {
123 	ROCKET_UNUSED(buffer);
124 	ROCKET_UNUSED(bytes);
125 
126 	ROCKET_ERRORMSG("No generic way to PushFront to a stream.");
127 	return false;
128 }
129 
130 // Push onto the back of the stream
PushBack(const void * buffer,size_t bytes)131 size_t Stream::PushBack(const void* buffer, size_t bytes)
132 {
133 	size_t pos = Tell();
134 	Seek(0, SEEK_END);
135 	size_t wrote = Write(buffer, bytes);
136 	Seek((long)pos, SEEK_SET);
137 	return wrote;
138 }
139 
140 // Push onto the front of the stream
PopFront(size_t ROCKET_UNUSED_PARAMETER (bytes))141 size_t Stream::PopFront(size_t ROCKET_UNUSED_PARAMETER(bytes))
142 {
143 	ROCKET_UNUSED(bytes);
144 
145 	ROCKET_ERRORMSG("No generic way to PopFront from a stream.");
146 	return 0;
147 }
148 
149 // Push onto the back of the stream
PopBack(size_t bytes)150 size_t Stream::PopBack(size_t bytes)
151 {
152 	return Truncate(Length() - bytes);
153 }
154 
155 // Sets the mode on the stream; should be called by a stream when it is opened.
SetStreamDetails(const URL & _url,int _stream_mode)156 void Stream::SetStreamDetails(const URL& _url, int _stream_mode)
157 {
158 	url = _url;
159 	stream_mode = _stream_mode;
160 }
161 
162 // Deletes the stream.
OnReferenceDeactivate()163 void Stream::OnReferenceDeactivate()
164 {
165 	Close();
166 	delete this;
167 }
168 
169 }
170 }
171