//============================================================================ // NDBHandlePool::Open : Open the database. //---------------------------------------------------------------------------- NStatus NDBHandlePool::Open(const NFile &theFile, NDBFlags theFlags, const NString &theVFS) { NDBHandlePtr dbHandle; NStatus theErr; // Validate our parameters and state NN_ASSERT(theFile.IsValid()); NN_ASSERT(!IsOpen()); // Update our state mFile = theFile; mFlags = theFlags; mVFS = theVFS; // Create the initial connection // // The initial connection allows us to test that we can actually open the // database, and may be all that we need if we're only to connect once. theErr = CreateConnection(dbHandle); NN_ASSERT_NOERR(theErr); mIsOpen = (dbHandle != NULL); if (mIsOpen) mPool.PushBack(dbHandle); return(theErr); }
//============================================================================ // NUnicodeParser::GetChar : Get a character. //---------------------------------------------------------------------------- utf32_t NUnicodeParser::GetChar(NIndex theIndex, bool toLower) const { NStringEncoder theEncoder; NRange theRange; const uint8_t *srcPtr; utf32_t theChar; // Validate our parameters NN_ASSERT(theIndex >= 0 && theIndex < GetSize()); // Get the state we need theRange = GetRange(theIndex); srcPtr = mData.GetData(theRange.GetLocation()); // Convert the character theChar = theEncoder.ConvertToUTF32(mEncoding, theRange.GetSize(), srcPtr); NN_ASSERT(theChar != 0); if (toLower) theChar = GetLower(theChar); return(theChar); }
//============================================================================ // NDBHandlePool::ReleaseConnection : Releae a connection. //---------------------------------------------------------------------------- void NDBHandlePool::ReleaseConnection(NDBHandlePtr &dbHandle) { // Validate our parameters and state NN_ASSERT(dbHandle != NULL); NN_ASSERT(mIsOpen); // Release a single connection if (mFlags & kNDBPoolConnectOnce) { NN_ASSERT(dbHandle == mPool.GetValue(0)); mPool.Unlock(); } // Release one of multiple connections else mPool.PushBack(dbHandle); // Clear the parameter dbHandle = NULL; }
//============================================================================ // TTestClient::ReceivedMessage : The client has received a message. //---------------------------------------------------------------------------- void TTestClient::ReceivedMessage(const NNetworkMessage &theMsg) { NString theValue; // Update our state mState += kStateClientReceivedMessage; // Handle the message switch (theMsg.GetType()) { case kTestClientBroadcastMsg: // Validate the message theValue = theMsg.GetValueString(kTestTokenKey); NN_ASSERT(theValue == kTokenClientBroadcast); break; case kTestServerClientMsg: // Validate the message theValue = theMsg.GetValueString(kTestTokenKey); NN_ASSERT(theValue == kTokenServerClient); // Update our state mIsDone = true; break; default: NMessageClient::ReceivedMessage(theMsg); break; } }
//============================================================================ // TSocketClient::ExecuteCustom : Execute a custom client test. //---------------------------------------------------------------------------- void TSocketClient::ExecuteCustom(bool *isDone, UInt16 thePort) { UInt32 n, theValue; NSocket *theSocket; NStatus theErr; // Open the socket theSocket = new NSocket(this); theSocket->Open("127.0.0.1", thePort); while (theSocket->GetStatus() != kNSocketOpened) NThread::Sleep(); // Get/set optins theErr = theSocket->SetOption(kNSocketNoDelay, (SInt32) true); NN_ASSERT_NOERR(theErr); theValue = theSocket->GetOption(kNSocketNoDelay); NN_ASSERT(theValue == (SInt32) true); // Write some data for (n = 0; n < kTestNumItems; n++) { theErr = theSocket->WriteUInt32(n); NN_ASSERT_NOERR(theErr); } // Read the response for (n = 0; n < kTestNumItems; n++) { theErr = theSocket->ReadUInt32(theValue); NN_ASSERT_NOERR(theErr); NN_ASSERT(theValue == (n * n)); } // Clean up theSocket->Close(); while (theSocket->GetStatus() != kNSocketClosed) NThread::Sleep(); delete theSocket; // Finish off *isDone = true; }
//============================================================================ // NTask::SetCommand : Set the command. //---------------------------------------------------------------------------- void NTask::SetCommand(const NString &theCmd) { // Validate our parameters and state NN_ASSERT(!theCmd.IsEmpty()); NN_ASSERT(!IsRunning()); // Set the command mCommand = theCmd; }
//============================================================================ // NSocketRequest::ProcessedData : Mark data as having been processed. //---------------------------------------------------------------------------- void NSocketRequest::ProcessedData(NIndex theSize) { // Validate our state NN_ASSERT(!IsFinished()); // Process the data mProcessed += theSize; NN_ASSERT(mProcessed <= mData.GetSize()); }
//============================================================================ // NUnicodeParser::GetCodePointsUTF16 : Get the code points from a UTF16 string. //---------------------------------------------------------------------------- NRangeList NUnicodeParser::GetCodePointsUTF16(const NRange &theBOM) const { NIndex n, theSize, charSize; NRangeList theResult; NRange theRange; const uint8_t *theData; utf16_t theChar; // Get the state we need theSize = mData.GetSize(); theData = mData.GetData(); NN_ASSERT((theSize % sizeof(utf16_t)) == 0); // Get the code points theResult.reserve(theSize / sizeof(utf16_t)); n = (theBOM.IsEmpty() ? 0 : theBOM.GetNext()); while (n < theSize) { // Get the character theChar = GetNativeUTF16(*((const utf16_t *) &theData[n]), mEncoding); charSize = 2; if (theChar >= kUTF16SurrogateHighStart && theChar <= kUTF16SurrogateHighEnd) { NN_ASSERT(n <= (theSize-2)); NN_ASSERT(GetNativeUTF16(*((const utf16_t *) &theData[n+2]), mEncoding) >= kUTF16SurrogateLowStart && GetNativeUTF16(*((const utf16_t *) &theData[n+2]), mEncoding) <= kUTF16SurrogateLowEnd); charSize += 2; } // Break on NULL if (theChar == 0x0000) break; // Add the code point theRange = NRange(n, charSize); theResult.push_back(theRange); n += charSize; } return(theResult); }
//============================================================================ // NThreadPool::Pause : Pause the pool. //---------------------------------------------------------------------------- void NThreadPool::Pause(void) { StLock acquireLock(mLock); // Validate our state NN_ASSERT(!mIsPaused); NN_ASSERT(mTasksPending.empty()); // Update our state mIsPaused = true; }
//============================================================================ // NMessageServer::SetMaxClients : Set the max clients. //---------------------------------------------------------------------------- void NMessageServer::SetMaxClients(NIndex maxClients) { // Validate our parameters and state NN_ASSERT(maxClients >= 1 && maxClients <= kNEntityClientsMax); NN_ASSERT(GetStatus() == kNServerStopped); // Set the max clients mMaxClients = maxClients; }
//============================================================================ // NUnicodeParser::AddBOM : Add a BOM prefix. //---------------------------------------------------------------------------- void NUnicodeParser::AddBOM(NData &theData, NStringEncoding theEncoding) const { NRange theRange; // Validate our parameters NN_ASSERT(NStringEncoder::IsEncodingUTF(theEncoding)); NN_ASSERT(GetBOM(theData, theRange) == kNStringEncodingInvalid); (void) theRange; // Add the BOM switch (theEncoding) { case kNStringEncodingUTF8: AddBOMToUTF8(theData); break; case kNStringEncodingUTF16: AddBOMToUTF16(theData, kNEndianNative); break; case kNStringEncodingUTF16BE: AddBOMToUTF16(theData, kNEndianBig); break; case kNStringEncodingUTF16LE: AddBOMToUTF16(theData, kNEndianLittle); break; case kNStringEncodingUTF32: AddBOMToUTF32(theData, kNEndianNative); break; case kNStringEncodingUTF32BE: AddBOMToUTF32(theData, kNEndianBig); break; case kNStringEncodingUTF32LE: AddBOMToUTF16(theData, kNEndianLittle); break; default: NN_LOG("Invalid encoding: %d", theEncoding); break; } }
//============================================================================ // TTestClient::~TTestClient : Destructor. //---------------------------------------------------------------------------- TTestClient::~TTestClient(void) { // Validate our state NN_ASSERT(GetStatus() == kNClientDisconnected); }
//============================================================================ // NTask::Launch : Launch the task. //---------------------------------------------------------------------------- NStatus NTask::Launch(void) { NStatus theErr; // Validate our state NN_ASSERT(!IsRunning()); // Clean up // // If we've been used to launch a task already, the task state may contain // open stdio streams, since they may contain some buffered output which // this process has still to read. // // Launching a new task means we can discard those streams, closing them // as necessary. NTargetSystem::TaskDestroy(mTask); // Launch the task mTask = NTargetSystem::TaskCreate(mCommand, mArguments); theErr = IsRunning() ? kNoErr : kNErrNotSupported; return(theErr); }
//============================================================================ // NTimer::ResetTimer : Reset a timer. //---------------------------------------------------------------------------- void NTimer::ResetTimer(NTime fireAfter, NTimerID theTimer) { StLock acquireLock(mLock); NTimerMapIterator theIter; // Adjust all timers if (theTimer == kNTimerAll) { for (theIter = mTimers.begin(); theIter != mTimers.end(); theIter++) NTargetTime::TimerReset(theIter->first, fireAfter); } // Adjust a single timer else { theIter = mTimers.find(theTimer); NN_ASSERT(theIter != mTimers.end()); if (theIter != mTimers.end()) NTargetTime::TimerReset(theIter->first, fireAfter); } }
//============================================================================ // NTimer::RemoveTimer : Remove a timer. //---------------------------------------------------------------------------- void NTimer::RemoveTimer(NTimerID theTimer) { StLock acquireLock(mLock); NTimerMapIterator theIter; // Remove all timers if (theTimer == kNTimerAll) { for (theIter = mTimers.begin(); theIter != mTimers.end(); theIter++) NTargetTime::TimerDestroy(theIter->first); mTimers.clear(); } // Remove a single timer else { theIter = mTimers.find(theTimer); NN_ASSERT(theIter != mTimers.end()); if (theIter != mTimers.end()) { NTargetTime::TimerDestroy(theIter->first); mTimers.erase(theIter); } } }
//============================================================================= // NGeometryUtilities::ComparePointToPolygon : Compare a point to a polygon. //----------------------------------------------------------------------------- template<class T> NGeometryComparison NGeometryUtilities::ComparePointToPolygon(const NPointT<T> &thePoint, NIndex numPoints, const NPointT<T> *thePoints) { bool p1Above, p2Above; SInt32 crossNum; NPointT<T> p1, p2; T c, w; NIndex n; // Validate our parameters NN_ASSERT(numPoints >= 3); // Test the polygon crossNum = 0; p1 = thePoints[numPoints-1]; p1Above = (p1.y > thePoint.y); for (n = 0; n < numPoints; n++) { // Look for a crossing in y p2 = thePoints[n]; p2Above = (p2.y > thePoint.y); if (p1Above != p2Above) { // If the segment is entirely to the left in x, it can't cross if (std::max(p1.x, p2.x) < thePoint.x) ; // If the segment is entirely to the right in x, it must cross else if (std::min(p1.x, p2.x) > thePoint.x) crossNum++; // Otherwise we need to check the intersection else { w = (thePoint.y - p1.y) / (p2.y - p1.y); c = p1.x + (w * (p2.x - p1.x)); if (thePoint.x < c) crossNum++; } } p1 = p2; p1Above = p2Above; } // Process the result if (NMathUtilities::IsOdd(crossNum)) return(kNGeometryInside); else return(kNGeometryOutside); }
//============================================================================ // NDate::SetDate : Set the date. //---------------------------------------------------------------------------- void NDate::SetDate(const NGregorianDate &theDate) { // Validate our parameters NN_ASSERT(theDate.month >= 1 && theDate.month <= 12); NN_ASSERT(theDate.day >= 1 && theDate.day <= 31); NN_ASSERT(theDate.hour >= 0 && theDate.hour <= 23); NN_ASSERT(theDate.minute >= 0 && theDate.minute <= 59); NN_ASSERT(theDate.second >= 0.0 && theDate.second <= 60.0); // Set the time mTime = NTargetTime::ConvertDateToTime(theDate); }
//============================================================================ // NFileUtilities::GetDirectorySize : Get a directory size. //---------------------------------------------------------------------------- uint64_t NFileUtilities::GetDirectorySize(const NFile &theDirectory) { NFileIterator fileIterator; NFileList theFiles; NFile theFile; uint64_t theSize; NFileListConstIterator theIter; // Validate our parameters NN_ASSERT(theDirectory.IsDirectory()); // Get the state we need theFiles = fileIterator.GetFiles(theDirectory); theSize = 0; // Get the size for (theIter = theFiles.begin(); theIter != theFiles.end(); theIter++) { theFile = *theIter; if (theFile.IsFile()) theSize += theFile.GetSize(); } return(theSize); }
//============================================================================ // NCGShading::UpdateShading : Update the shading. //---------------------------------------------------------------------------- void NCGShading::UpdateShading(void) const { CGColorSpaceRef cgColorSpace; // Validate our state NN_ASSERT(!mShading.IsValid()); // Create the new shading cgColorSpace = NCGColor::GetDeviceRGB(); switch (mMode) { case kShadingNone: ResetShading(); break; case kShadingLinear: mShading.SetObject(CGShadingCreateAxial( cgColorSpace, ToCG(mStartPoint), ToCG(mEndPoint), mEvaluate, mStartExtend, mEndExtend)); break; case kShadingRadial: mShading.SetObject(CGShadingCreateRadial(cgColorSpace, ToCG(mStartPoint), mStartRadius, ToCG(mEndPoint), mEndRadius, mEvaluate, mStartExtend, mEndExtend)); break; default: NN_LOG("Unknown shading mode: %d", mMode); break; } }
//============================================================================ // TTestServer::~TTestServer : Destructor. //---------------------------------------------------------------------------- TTestServer::~TTestServer(void) { // Validate our state NN_ASSERT(GetStatus() == kNServerStopped); }
//============================================================================ // NThreadPool::ScheduleTask : Schedule a task for execution. //---------------------------------------------------------------------------- void NThreadPool::ScheduleTask(NThreadTask *theTask) { // Validate our state NN_ASSERT(mLock.IsLocked()); // Add the task PushTask(mTasks, theTask); mHavePushed = true; // Update the workers // // If we've reached the thread limit then the existing threads will need to // process this task, so we signal to let them know there's more work to do. // // Incrementing the thread count must be done by the main thread, since a large // number of tasks may be queued up before any worker thread gets a chance to run. if (mActiveThreads < mThreadLimit) NThreadUtilities::DetachFunctor(BindSelf(NThreadPool::ExecuteTasks)); mSemaphore.Signal(); }
//============================================================================ // NThreadPool::Resume : Resume the pool. //---------------------------------------------------------------------------- void NThreadPool::Resume(void) { StLock acquireLock(mLock); NThreadTaskListIterator theIter; // Validate our state NN_ASSERT(mIsPaused); // Schedule the tasks // // The threads are blocked until we release the lock, so any sorting // of the task list will be deferred until the first thread can run. for (theIter = mTasksPending.begin(); theIter != mTasksPending.end(); theIter++) ScheduleTask(*theIter); // Update our state mIsPaused = false; mTasksPending.clear(); }
//============================================================================ // NFileUtilities::SetFileData : Set a file to data. //---------------------------------------------------------------------------- NStatus NFileUtilities::SetFileData(const NFile &theFile, const NData &theData) { uint64_t theSize, numWritten; NFile mutableFile; NStatus theErr; // Get the state we need mutableFile = theFile; theSize = theData.GetSize(); // Open the file theErr = mutableFile.Open(kNPermissionUpdate, true); if (theErr != kNoErr) return(theErr); // Write the data theErr = mutableFile.SetSize(0); theErr |= mutableFile.Write(theSize, theData.GetData(), numWritten); NN_ASSERT_NOERR(theErr); NN_ASSERT(numWritten == theSize); // Clean up mutableFile.Close(); return(theErr); }
//============================================================================ // NDataEncoder::B64_Encode : Encode to Base64. //---------------------------------------------------------------------------- NString NDataEncoder::B64_Encode(const NData &theValue) { NData theBuffer; NString theString; base64_encodestate theState; char *dataPtr; NIndex dataSize; // Get the state we need base64_init_encodestate(&theState); if (theValue.IsEmpty() || !theBuffer.SetSize(theValue.GetSize() * 2)) return(theString); // Encode the value dataPtr = (char *) theBuffer.GetData(); dataSize = base64_encode_block((const char *) theValue.GetData(), theValue.GetSize(), dataPtr, &theState); theString = NString(dataPtr, dataSize); dataSize = base64_encode_blockend(dataPtr, &theState); if (dataSize != 0) theString += NString(dataPtr, dataSize); // Remove the trailing newline NN_ASSERT(theString.GetRight(1) == "\n"); theString.TrimRight(1); return(theString); }
//============================================================================ // NFileUtilities::GetFileText : Get a file as text. //---------------------------------------------------------------------------- NString NFileUtilities::GetFileText(const NFile &theFile, NStringEncoding theEncoding) { NStringEncoder theEncoder; NData theData; NString theText; // Get the state we need theData = GetFileData(theFile); if (theData.IsEmpty()) return(theText); // Get the text if (theEncoding == kNStringEncodingInvalid) { theEncoding = theEncoder.GetEncoding(theData); NN_ASSERT(theEncoding != kNStringEncodingInvalid); } if (theEncoding != kNStringEncodingInvalid) theText = NString(theData, theEncoding); return(theText); }
//============================================================================ // NTargetNetwork::SocketSetOption : Set a socket option. //---------------------------------------------------------------------------- NStatus NTargetNetwork::SocketSetOption(NSocketRef theSocket, NSocketOption theOption, int32_t theValue) { int valueInt; NStatus theErr; // Validate our parameters NN_ASSERT(theSocket->nativeSocket != kSocketHandleInvalid); // Get the state we need theErr = kNErrNotSupported; // Set the option switch (theOption) { case kNSocketNoDelay: valueInt = (theValue != 0) ? 1 : 0; if (setsockopt(theSocket->nativeSocket, IPPROTO_TCP, TCP_NODELAY, &valueInt, sizeof(valueInt)) == 0) theErr = kNoErr; break; default: NN_LOG("Unknown option: %d", theOption); break; } return(theErr); }
//============================================================================= // NBroadcaster::CloneBroadcaster : Clone a broadcaster. //----------------------------------------------------------------------------- void NBroadcaster::CloneBroadcaster(const NBroadcaster &theBroadcaster) { NListenerMapConstIterator theIter; // Validate our state NN_ASSERT(mBroadcasts.empty()); // Clone the broadcaster // // An explicit clone is necessary to ensure the pointers between listener and // broadcaster are correctly established (the default copy constructor would // copy the pointers in this object, but wouldn't update the other). // // Cloning a broadcaster that's currently broadcasting will clone the listeners // so that future broadcasts go to the same place - however we don't clone the // list of active broadcasts, since we're not ourselves broadcasting. mIsBroadcasting = theBroadcaster.mIsBroadcasting; mBroadcasts.clear(); for (theIter = theBroadcaster.mListeners.begin(); theIter != theBroadcaster.mListeners.end(); theIter++) AddListener(theIter->first); }
//============================================================================ // NCache::SetValue : Set a value. //---------------------------------------------------------------------------- void NCache::SetValue(const NCacheKey &theKey, NCacheValue *theValue) { // Validate our parameters NN_ASSERT(theValue->GetCost() >= 0); // Prepare to set if (HasKey(theKey)) RemoveKey(theKey); if (NeedsPurge()) Purge(); // Set the value mCache[theKey] = theValue; mCacheCost += theValue->GetCost(); theValue->SetAccessTime(); theValue->Retain(); }
//============================================================================ // NSocketRequest::GetUnprocessedSize : Get the unprocessed size. //---------------------------------------------------------------------------- NIndex NSocketRequest::GetUnprocessedSize(void) const { NIndex theSize; // Validate our state NN_ASSERT(!IsFinished()); // Get the size theSize = mData.GetSize() - mProcessed; NN_ASSERT(theSize >= 1); return(theSize); }
//============================================================================ // NTargetNetwork::SocketGetOption : Get a socket option. //---------------------------------------------------------------------------- int32_t NTargetNetwork::SocketGetOption(NSocketRef theSocket, NSocketOption theOption) { socklen_t valueSize; int valueInt; int32_t theValue; // Validate our parameters NN_ASSERT(theSocket->nativeSocket != kSocketHandleInvalid); // Get the state we need theValue = 0; // Get the option switch (theOption) { case kNSocketNoDelay: valueInt = 0; valueSize = sizeof(valueInt); if (getsockopt(theSocket->nativeSocket, IPPROTO_TCP, TCP_NODELAY, &valueInt, &valueSize) == 0) theValue = (valueInt != 0); break; default: NN_LOG("Unknown option: %d", theOption); break; } return(theValue); }