// This file is part of the ustl library, an STL implementation. // // Copyright (C) 2005 by Mike Sharov <msharov@users.sourceforge.net> // This file is free software, distributed under the MIT License. // // cmemlink.cc // // See cmemlink.h for documentation. // #include "cmemlink.h" #include "ofstream.h" #include "strmsize.h" #include "ualgo.h" #include "uassert.h" #if PLATFORM_ANDROID #include <stdio.h> #undef CPU_HAS_MMX #endif namespace ustl { /// \brief Attaches the object to pointer \p p of size \p n. /// /// If \p p is NULL and \p n is non-zero, bad_alloc is thrown and current /// state remains unchanged. /// void cmemlink::link (const void* p, size_type n) { if (!p && n) #if PLATFORM_ANDROID printf("bad alloc\n"); #else /* !PLATFORM_ANDROID */ throw bad_alloc (n); #endif unlink(); relink (p, n); } /// Writes the object to stream \p os void cmemlink::write (ostream& os) const { const written_size_type sz (size()); assert (sz == size() && "No support for writing memblocks larger than 4G"); os << sz; os.write (cdata(), sz); os.align (alignof (sz)); } /// Writes the object to stream \p os void cmemlink::text_write (ostringstream& os) const { os.write (begin(), readable_size()); } /// Returns the number of bytes required to write this object to a stream. cmemlink::size_type cmemlink::stream_size (void) const { const written_size_type sz (size()); return (Align (stream_size_of (sz) + sz, alignof(sz))); } /// Writes the data to file \p "filename". void cmemlink::write_file (const char* filename, int mode) const { fstream f; f.exceptions (fstream::allbadbits); f.open (filename, fstream::out | fstream::trunc, mode); f.write (cdata(), readable_size()); f.close(); } /// swaps the contents with \p l void cmemlink::swap (cmemlink& l) { #if CPU_HAS_MMX && SIZE_OF_POINTER == 4 asm ( "movq %0, %%mm0\n\t" "movq %2, %%mm1\n\t" "movq %%mm0, %2\n\t" "movq %%mm1, %0" : "=m"(m_Data), "=m"(m_Size), "=m"(l.m_Data), "=m"(l.m_Size) : : "mm0", "mm1", "st", "st(1)"); simd::reset_mmx(); #elif CPU_HAS_SSE && SIZE_OF_POINTER == 8 asm ( "movups %0, %%xmm0\n\t" "movups %2, %%xmm1\n\t" "movups %%xmm0, %2\n\t" "movups %%xmm1, %0" : "=m"(m_Data), "=m"(m_Size), "=m"(l.m_Data), "=m"(l.m_Size) : : "xmm0", "xmm1"); #else ::ustl::swap (m_Data, l.m_Data); ::ustl::swap (m_Size, l.m_Size); #endif } /// Compares to memory block pointed by l. Size is compared first. bool cmemlink::operator== (const cmemlink& l) const { return (l.m_Size == m_Size && (l.m_Data == m_Data || 0 == memcmp (l.m_Data, m_Data, m_Size))); } } // namespace ustl