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