/* * 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 "TimeUnit.h" #include #include using namespace decaf; using namespace decaf::lang; using namespace decaf::lang::exceptions; using namespace decaf::util; using namespace decaf::util::concurrent; //////////////////////////////////////////////////////////////////////////////// const TimeUnit TimeUnit::NANOSECONDS( 0, "NANOSECONDS" ); const TimeUnit TimeUnit::MICROSECONDS( 1, "MICROSECONDS" ); const TimeUnit TimeUnit::MILLISECONDS( 2, "MILLISECONDS" ); const TimeUnit TimeUnit::SECONDS( 3, "SECONDS" ); const TimeUnit TimeUnit::MINUTES( 4, "MINUTES" ); const TimeUnit TimeUnit::HOURS( 5, "HOURS" ); const TimeUnit TimeUnit::DAYS( 6, "DAYS" ); //////////////////////////////////////////////////////////////////////////////// const TimeUnit* const TimeUnit::values[] = { &NANOSECONDS, &MICROSECONDS, &MILLISECONDS, &SECONDS, &MINUTES, &HOURS, &DAYS }; //////////////////////////////////////////////////////////////////////////////// const long long TimeUnit::multipliers[] = { 1, 1000LL, 1000LL * 1000LL, 1000LL * 1000LL * 1000LL, 1000LL * 1000LL * 1000LL * 60LL, 1000LL * 1000LL * 1000LL * 60LL * 60LL, 1000LL * 1000LL * 1000LL * 60LL * 60LL * 24LL, }; //////////////////////////////////////////////////////////////////////////////// TimeUnit::TimeUnit( int index, const std::string& name ) : index(index), name(name) { } //////////////////////////////////////////////////////////////////////////////// long long TimeUnit::convert( long long sourceDuration, const TimeUnit& sourceUnit ) const { return this->doConvert( sourceUnit.index, this->index, sourceDuration ); } //////////////////////////////////////////////////////////////////////////////// long long TimeUnit::doConvert( int srcIndex, int destIndex, long long duration ) const { if( duration == 0 ) { return duration; } else if( srcIndex > destIndex ) { return scale( duration, multipliers[srcIndex] / multipliers[destIndex], Long::MAX_VALUE / ( multipliers[srcIndex] / multipliers[destIndex] ) ); } else if( srcIndex < destIndex ) { return duration / ( multipliers[destIndex] / multipliers[srcIndex] ); } // Same unit, no conversion. return duration; } //////////////////////////////////////////////////////////////////////////////// int TimeUnit::excessNanos( long long time, long long ms ) const { if( *this == NANOSECONDS ) { return (int)( time - ( ms * 1000 * 1000 ) ); } else if( *this == MICROSECONDS ) { return (int)( ( time * 1000 ) - ( ms * 1000 * 1000 ) ); } return 0; } //////////////////////////////////////////////////////////////////////////////// void TimeUnit::sleep( long long timeout ) const { if( timeout > 0 ) { long long ms = toMillis( timeout ); int ns = excessNanos( timeout, ms ); Thread::sleep( ms, ns ); } } //////////////////////////////////////////////////////////////////////////////// void TimeUnit::timedWait( Synchronizable* obj, long long timeout ) const { if( obj == NULL ) { throw NullPointerException( __FILE__, __LINE__, "Synchronizable object pointer was null." ); } if( timeout > 0 ) { long long ms = toMillis( timeout ); int ns = excessNanos( timeout, ms ); obj->wait( ms, ns ); } } //////////////////////////////////////////////////////////////////////////////// void TimeUnit::timedJoin( Thread* thread, long long timeout ) { if( thread == NULL ) { throw NullPointerException( __FILE__, __LINE__, "Thread object pointer was null." ); } if( timeout > 0 ) { long long ms = toMillis( timeout ); int ns = excessNanos( timeout, ms ); thread->join( ms, ns ); } } //////////////////////////////////////////////////////////////////////////////// std::string TimeUnit::toString() const { return this->name; } //////////////////////////////////////////////////////////////////////////////// int TimeUnit::compareTo( const TimeUnit& value ) const { return index == value.index ? 0 : ( index > value.index ? 1 : -1 ); } //////////////////////////////////////////////////////////////////////////////// bool TimeUnit::equals( const TimeUnit& value ) const { return index == value.index; } //////////////////////////////////////////////////////////////////////////////// bool TimeUnit::operator==( const TimeUnit& value ) const { return index == value.index; } //////////////////////////////////////////////////////////////////////////////// bool TimeUnit::operator<( const TimeUnit& value ) const { return this->compareTo( value ) == -1; } //////////////////////////////////////////////////////////////////////////////// long long TimeUnit::scale( long long duration, long long multiplier, long long overflow ) { if( duration > overflow ) { return Long::MAX_VALUE; } else if( duration < -overflow ) { return Long::MIN_VALUE; } return duration * multiplier; } //////////////////////////////////////////////////////////////////////////////// const TimeUnit& TimeUnit::valueOf( const std::string& name ) { for( int i = 0; i < 7; ++i ) { if( values[i]->name == name ) { return *values[i]; } } throw IllegalArgumentException( __FILE__, __LINE__, "Passed TimeUnit name; %s, Does not match any instances of TimeUnit", name.c_str() ); }