You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
156 lines
4.6 KiB
156 lines
4.6 KiB
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: $RCSfile: vtkBase64InputStream.cxx,v $
|
|
|
|
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
|
|
All rights reserved.
|
|
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
|
|
|
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
PURPOSE. See the above copyright notice for more information.
|
|
|
|
=========================================================================*/
|
|
#include "vtkBase64InputStream.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkBase64Utilities.h"
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkCxxRevisionMacro(vtkBase64InputStream, "$Revision: 1.4 $");
|
|
vtkStandardNewMacro(vtkBase64InputStream);
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkBase64InputStream::vtkBase64InputStream()
|
|
{
|
|
this->BufferLength = 0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkBase64InputStream::~vtkBase64InputStream()
|
|
{
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkBase64InputStream::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os, indent);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
inline int vtkBase64InputStream::DecodeTriplet(unsigned char& c0,
|
|
unsigned char& c1,
|
|
unsigned char& c2)
|
|
{
|
|
// Read the 4 bytes encoding this triplet from the stream.
|
|
|
|
unsigned char in[4];
|
|
this->Stream->read(reinterpret_cast<char*>(in), 4);
|
|
if(this->Stream->gcount() < 4) { return 0; }
|
|
|
|
return vtkBase64Utilities::DecodeTriplet(in[0], in[1], in[2], in[3],
|
|
&c0, &c1, &c2);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkBase64InputStream::StartReading()
|
|
{
|
|
this->Superclass::StartReading();
|
|
this->BufferLength = 0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkBase64InputStream::EndReading()
|
|
{
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkBase64InputStream::Seek(unsigned long offset)
|
|
{
|
|
unsigned long triplet = offset/3;
|
|
int skipLength = offset%3;
|
|
|
|
// Seek to the beginning of the encoded triplet containing the
|
|
// offset.
|
|
if(!this->Stream->seekg(this->StreamStartPosition+(triplet*4)))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
// Decode the first triplet if it is paritally skipped.
|
|
if(skipLength == 0)
|
|
{
|
|
this->BufferLength = 0;
|
|
}
|
|
else if(skipLength == 1)
|
|
{
|
|
unsigned char c;
|
|
this->BufferLength =
|
|
this->DecodeTriplet(c, this->Buffer[0], this->Buffer[1]) - 1;
|
|
}
|
|
else
|
|
{
|
|
unsigned char c[2];
|
|
this->BufferLength =
|
|
this->DecodeTriplet(c[0], c[1], this->Buffer[0]) - 2;
|
|
}
|
|
|
|
// A DecodeTriplet call may have failed to read the stream.
|
|
// If so, the current buffer length will be negative.
|
|
return ((this->BufferLength >= 0) ? 1:0);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
unsigned long vtkBase64InputStream::Read(unsigned char* data,
|
|
unsigned long length)
|
|
{
|
|
unsigned char* out = data;
|
|
unsigned char* end = data + length;
|
|
|
|
// If the previous read ended before filling buffer, don't read
|
|
// more.
|
|
if(this->BufferLength < 0) { return 0; }
|
|
|
|
// Use leftover characters from a previous decode.
|
|
if((out != end) && (this->BufferLength == 2))
|
|
{
|
|
*out++ = this->Buffer[0];
|
|
this->Buffer[0] = this->Buffer[1];
|
|
this->BufferLength = 1;
|
|
}
|
|
if((out != end) && (this->BufferLength == 1))
|
|
{
|
|
*out++ = this->Buffer[0];
|
|
this->BufferLength = 0;
|
|
}
|
|
|
|
// Decode all complete triplets.
|
|
while((end - out) >= 3)
|
|
{
|
|
int len = this->DecodeTriplet(out[0], out[1], out[2]);
|
|
out += len;
|
|
if(len < 3)
|
|
{
|
|
this->BufferLength = len-3;
|
|
return (out-data);
|
|
}
|
|
}
|
|
|
|
// Decode the last triplet and save leftover characters in the buffer.
|
|
if((end - out) == 2)
|
|
{
|
|
int len = this->DecodeTriplet(out[0], out[1], this->Buffer[0]);
|
|
this->BufferLength = len-2;
|
|
if(len > 2) { out += 2; }
|
|
else { out += len; }
|
|
}
|
|
else if((end - out) == 1)
|
|
{
|
|
int len = this->DecodeTriplet(out[0], this->Buffer[0], this->Buffer[1]);
|
|
this->BufferLength = len-1;
|
|
if(len > 1) { out += 1; }
|
|
else { out += len; }
|
|
}
|
|
|
|
return (out-data);
|
|
}
|
|
|