blob: 5f615c439222d390b715bee0b97cd7d27a2f9bbc [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "String.h"
#include <decaf/lang/ArrayPointer.h>
#include <decaf/lang/System.h>
#include <decaf/lang/exceptions/NullPointerException.h>
#include <decaf/lang/exceptions/IndexOutOfBoundsException.h>
#include <decaf/lang/Short.h>
#include <decaf/lang/Integer.h>
#include <decaf/lang/Long.h>
#include <decaf/lang/Float.h>
#include <decaf/lang/Double.h>
using namespace std;
using namespace decaf;
using namespace decaf::lang;
using namespace decaf::lang::exceptions;
////////////////////////////////////////////////////////////////////////////////
namespace decaf{
namespace lang{
class Contents {
public:
ArrayPointer<unsigned char> value;
int length;
int offset;
public:
Contents() : value(), length( 0 ), offset( 0 ) {
}
Contents( int length ) : value( length ), length( length ), offset( 0 ) {
}
};
}}
////////////////////////////////////////////////////////////////////////////////
String::String() : contents(new Contents()) {
}
////////////////////////////////////////////////////////////////////////////////
String::String( const String& source ) : contents(new Contents(source.length())) {
// TODO
// load the passed string into the contents value.
//System::arraycopy( (unsigned char*)source.c_str(), 0, contents->value.get(), 0, source.length() );
}
////////////////////////////////////////////////////////////////////////////////
String::String( const std::string& source ) : contents(new Contents((int)source.length())) {
// load the passed string into the contents value.
System::arraycopy( (unsigned char*)source.c_str(), 0, contents->value.get(), 0, source.length() );
}
////////////////////////////////////////////////////////////////////////////////
String::String(const char* array, int size) : contents(new Contents) {
if( size < 0 ) {
throw IndexOutOfBoundsException(
__FILE__, __LINE__, "size parameter out of Bounds: %d.", size );
}
if( array == NULL ) {
throw NullPointerException(
__FILE__, __LINE__, "Buffer pointer passed was NULL." );
}
if(size > 0) {
this->contents->value = ArrayPointer<unsigned char>(size);
this->contents->length = size;
System::arraycopy( (unsigned char*)array, 0, contents->value.get(), 0, size );
}
}
////////////////////////////////////////////////////////////////////////////////
String::String(const char* array, int size, int offset, int length) : contents(new Contents) {
if( size < 0 ) {
throw IndexOutOfBoundsException(
__FILE__, __LINE__, "size parameter out of Bounds: %d.", size );
}
if( offset > size || offset < 0 ) {
throw IndexOutOfBoundsException(
__FILE__, __LINE__, "offset parameter out of Bounds: %d.", offset );
}
if( length < 0 || length > size - offset ) {
throw IndexOutOfBoundsException(
__FILE__, __LINE__, "length parameter out of Bounds: %d.", length );
}
if( array == NULL ) {
throw NullPointerException(
__FILE__, __LINE__, "Buffer pointer passed was NULL." );
}
if(size > 0) {
this->contents->value = ArrayPointer<unsigned char>(length);
this->contents->length = length;
System::arraycopy( (unsigned char*)array, offset, contents->value.get(), 0, length );
}
}
////////////////////////////////////////////////////////////////////////////////
String::~String() {
try{
delete this->contents;
}
DECAF_CATCH_NOTHROW( Exception )
DECAF_CATCHALL_NOTHROW()
}
////////////////////////////////////////////////////////////////////////////////
int String::length() const {
return this->contents->offset + this->contents->length;
}
////////////////////////////////////////////////////////////////////////////////
bool String::isEmpty() const {
return ( this->contents->offset + this->contents->length ) == 0;
}
////////////////////////////////////////////////////////////////////////////////
char String::charAt( int index ) const {
try{
if( index < 0 || index >= this->length() ) {
throw IndexOutOfBoundsException(
__FILE__, __LINE__, "Index given is out of bounds: %d.", index );
}
return this->contents->value[this->contents->offset + index];
}
DECAF_CATCH_RETHROW( IndexOutOfBoundsException )
DECAF_CATCHALL_THROW( IndexOutOfBoundsException )
}
////////////////////////////////////////////////////////////////////////////////
CharSequence* String::subSequence( int start DECAF_UNUSED, int end DECAF_UNUSED ) const {
try{
if( start > end ) {
throw IndexOutOfBoundsException(
__FILE__, __LINE__, "Start index is greater than end index." );
}
if( end - start > this->length() ) {
throw IndexOutOfBoundsException(
__FILE__, __LINE__, "Requested Range is greater than the String length." );
}
return NULL;
}
DECAF_CATCH_RETHROW( IndexOutOfBoundsException )
DECAF_CATCHALL_THROW( IndexOutOfBoundsException )
}
////////////////////////////////////////////////////////////////////////////////
std::string String::toString() const {
if( this->contents->value == NULL ) {
return "null";
}
return std::string( (const char*)this->contents->value.get(), this->length() );
}
////////////////////////////////////////////////////////////////////////////////
String String::valueOf(bool value) {
if(value) {
return String("true");
}
return String("false");
}
////////////////////////////////////////////////////////////////////////////////
String String::valueOf(char value) {
return String( &value, 1 );
}
////////////////////////////////////////////////////////////////////////////////
String String::valueOf(float value) {
return String( Float::toString(value) );
}
////////////////////////////////////////////////////////////////////////////////
String String::valueOf(double value) {
return String( Double::toString(value) );
}
////////////////////////////////////////////////////////////////////////////////
String String::valueOf(short value) {
return String( Short::toString(value) );
}
////////////////////////////////////////////////////////////////////////////////
String String::valueOf(int value) {
return String( Integer::toString(value) );
}
////////////////////////////////////////////////////////////////////////////////
String String::valueOf(long long value) {
return String( Long::toString(value) );
}