// // Copyright (c) 1993-2022 Robert McNeel & Associates. All rights reserved. // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert // McNeel & Associates. // // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF // MERCHANTABILITY ARE HEREBY DISCLAIMED. // // For complete openNURBS copyright information see . // //////////////////////////////////////////////////////////////// #include "opennurbs.h" #if !defined(ON_COMPILING_OPENNURBS) // This check is included in all opennurbs source .c and .cpp files to insure // ON_COMPILING_OPENNURBS is defined when opennurbs source is compiled. // When opennurbs source is being compiled, ON_COMPILING_OPENNURBS is defined // and the opennurbs .h files alter what is declared and how it is declared. #error ON_COMPILING_OPENNURBS must be defined when compiling opennurbs #endif ON_Workspace::ON_Workspace() : m_pFileBlk(0) , m_pMemBlk(0) {} ON_Workspace::~ON_Workspace() { Destroy(); } struct ON_Workspace_FBLK { struct ON_Workspace_FBLK* pNext; FILE* pFile; } * m_pFileBlk; struct ON_Workspace_MBLK { struct ON_Workspace_MBLK* pNext; void* pMem; } * m_pMemBlk; void ON_Workspace::Destroy() { struct ON_Workspace_FBLK* pFileBlk = m_pFileBlk; while ( pFileBlk ) { if ( pFileBlk->pFile ) fclose( pFileBlk->pFile ); pFileBlk = pFileBlk->pNext; } m_pFileBlk = 0; struct ON_Workspace_MBLK* pNext = m_pMemBlk; struct ON_Workspace_MBLK* p = nullptr; while ( pNext ) { p = pNext; pNext = pNext->pNext; if ( p->pMem ) { onfree(p->pMem); p->pMem = nullptr; } onfree( p ); } m_pMemBlk = 0; } void* ON_Workspace::GetMemory( size_t size ) { void* p = nullptr; if ( size > 0 ) { struct ON_Workspace_MBLK* pBlk = (struct ON_Workspace_MBLK*)onmalloc(sizeof(*pBlk)); if ( pBlk ) { pBlk->pMem = p = onmalloc(size); pBlk->pNext = m_pMemBlk; m_pMemBlk = pBlk; } } return p; } void* ON_Workspace::GrowMemory( void* p, size_t size ) { void* newp = nullptr; if ( !p ) { newp = GetMemory(size); } else { struct ON_Workspace_MBLK* pBlk = m_pMemBlk; while ( pBlk ) { if ( pBlk->pMem == p ) { if ( size > 0 ) { newp = onrealloc(p,size); } else { newp = p; } pBlk->pMem = newp; break; } pBlk = pBlk->pNext; } } return newp; } void ON_Workspace::KeepAllMemory() { struct ON_Workspace_MBLK* p; struct ON_Workspace_MBLK* pNext = m_pMemBlk; m_pMemBlk = 0; while ( pNext ) { p = pNext; pNext = pNext->pNext; p->pMem = 0; // caller want to manage this heap onfree( p ); } } bool ON_Workspace::KeepMemory( void* p ) { int rc = false; if ( p ) { struct ON_Workspace_MBLK* pPrevBlk = nullptr; struct ON_Workspace_MBLK* pBlk = m_pMemBlk; while ( pBlk ) { if ( pBlk->pMem == p ) { // Remove pBlk from list so ~ON_Workspace() won't onfree() its memory // and any future GrowMemory...() or KeepMemory() calls won't have // to search past it. pBlk->pMem = nullptr; if ( pPrevBlk ) { pPrevBlk->pNext = pBlk->pNext; } else { m_pMemBlk = pBlk->pNext; } onfree( pBlk ); rc = true; break; } pPrevBlk = pBlk; pBlk = pBlk->pNext; } } return rc; } int* ON_Workspace::GetIntMemory( size_t size ) { int* pi = (int*)(GetMemory(size*sizeof(*pi))); return pi; } double* ON_Workspace::GetDoubleMemory( size_t size ) { double* pd = (double*)(GetMemory(size*sizeof(*pd))); return pd; } ON_3dPoint* ON_Workspace::GetPointMemory( size_t size ) { ON_3dPoint* p3d = (ON_3dPoint*)(GetMemory(size*sizeof(*p3d))); return p3d; } ON_3dVector* ON_Workspace::GetVectorMemory( size_t size ) { ON_3dVector* v3d = (ON_3dVector*)(GetMemory(size*sizeof(*v3d))); return v3d; } int** ON_Workspace::GetIntMemory( size_t row_count, size_t col_count ) { int** p = 0; size_t i; if ( row_count > 0 && col_count > 0 ) { p = (int**)GetMemory(row_count*(sizeof(*p) + col_count*sizeof(**p))); if ( p ) { p[0] = (int*)(p+row_count); for( i = 1; i < row_count; i++ ) { p[i] = p[i-1] + col_count; } } } return p; } double** ON_Workspace::GetDoubleMemory( size_t row_count, size_t col_count ) { double** p = 0; size_t i; if ( row_count > 0 && col_count > 0 ) { // i keeps doubles aligned i = (sizeof(*p) < sizeof(**p)) ? (row_count + (row_count%2)) : row_count; p = (double**)GetMemory(i*sizeof(*p) + row_count*col_count*sizeof(**p)); if ( p ) { p[0] = (double*)(p+i); for( i = 1; i < row_count; i++ ) { p[i] = p[i-1] + col_count; } } } return p; } int* ON_Workspace::GrowIntMemory( int* p, size_t size ) { int* pi = (int*)(GrowMemory(p,size*sizeof(*pi))); return pi; } double* ON_Workspace::GrowDoubleMemory( double* p, size_t size ) { double* pd = (double*)(GrowMemory(p,size*sizeof(*pd))); return pd; } ON_3dPoint* ON_Workspace::GrowPointMemory( ON_3dPoint* p, size_t size ) { ON_3dPoint* p3d = (ON_3dPoint*)(GrowMemory(p,size*sizeof(*p3d))); return p3d; } ON_3dVector* ON_Workspace::GrowVectorMemory( ON_3dVector* p, size_t size ) { ON_3dVector* v3d = (ON_3dVector*)(GrowMemory(p,size*sizeof(*v3d))); return v3d; } FILE* ON_Workspace::OpenFile( const char* sFileName, const char* sMode ) { FILE* pFile = ON::OpenFile( sFileName, sMode ); if ( pFile ) { struct ON_Workspace_FBLK* pFileBlk = (struct ON_Workspace_FBLK*)GetMemory( sizeof(*pFileBlk) ); pFileBlk->pNext = m_pFileBlk; pFileBlk->pFile = pFile; m_pFileBlk = pFileBlk; } return pFile; } FILE* ON_Workspace::OpenFile( const wchar_t* sFileName, const wchar_t* sMode ) { FILE* pFile = ON::OpenFile( sFileName, sMode ); if ( pFile ) { struct ON_Workspace_FBLK* pFileBlk = (struct ON_Workspace_FBLK*)GetMemory( sizeof(*pFileBlk) ); pFileBlk->pNext = m_pFileBlk; pFileBlk->pFile = pFile; m_pFileBlk = pFileBlk; } return pFile; } bool ON_Workspace::KeepFile( FILE* pFile ) { bool rc = false; if ( pFile ) { struct ON_Workspace_FBLK* pFileBlk = m_pFileBlk; while ( pFileBlk ) { if ( pFileBlk->pFile == pFile ) { pFileBlk->pFile = nullptr; rc = true; break; } pFileBlk = pFileBlk->pNext; } } return rc; }