beast cleaning and tidying:

* Consolidate small modules into one
* Remove Android-specific platform support
* Remove Chrono.h from beast_core.h
* Removed files:
  - TypeTraits.h
  - Utility.h
  - Net.h
  - Asio.h
* Remove zlib support:
  - Remove inline zlib library sources
  - Remove GZIPCompressorOutputStream
  - Remove GZIPDecompressorInputStream
* Remove obsolete or unused classes:
  - AbstractObject
  - BigInteger
  - BufferedInputStream
  - CacheLine
  - CPUMeter
  - DatagramSocket
  - DynamicObject
  - FileLogger
  - FPUFlags
  - Identifier
  - JSON
  - LocalisedStrings
  - MACAddress
  - MemoryAlignment
  - MemoryInputStream
  - MemoryMappedFile
  - NamedValueSet
  - OptionalScopedPointer
  - PerformanceCounter
  - PropertySet
  - ScopedTimeInterval
  - SparseSet
  - SpinDelay
  - StreamingSocket
  - StringPool
  - SubregionStream
  - Uuid
  - Variant
This commit is contained in:
Vinnie Falco
2014-03-20 18:08:54 -07:00
parent 761affacc3
commit 2d490f6e6a
142 changed files with 129 additions and 25187 deletions

View File

@@ -26,8 +26,8 @@
// This module requires boost and possibly OpenSSL
#include "system/BoostIncludes.h"
#include "../../beast/Utility.h"
#include "../../beast/HTTP.h"
#include "../../beast/http/URL.h"
#include "../../beast/http/ParsedURL.h"
#include "../../beast/asio/IPAddressConversion.h"

View File

@@ -20,6 +20,8 @@
#ifndef BEAST_ASIO_HTTPMESSAGE_H_INCLUDED
#define BEAST_ASIO_HTTPMESSAGE_H_INCLUDED
#include "../../../beast/net/DynamicBuffer.h"
namespace beast {
/** A complete HTTP message.

View File

@@ -126,13 +126,7 @@
#undef _aligned_msize
#endif
#include "containers/DynamicObject.cpp"
#include "containers/NamedValueSet.cpp"
#include "containers/PropertySet.cpp"
#include "containers/Variant.cpp"
#include "diagnostic/FatalError.cpp"
#include "diagnostic/FPUFlags.cpp"
#include "diagnostic/SemanticVersion.cpp"
#include "diagnostic/UnitTest.cpp"
#include "diagnostic/UnitTestUtilities.cpp"
@@ -145,68 +139,42 @@
#include "files/RandomAccessFile.cpp"
#include "files/TemporaryFile.cpp"
#include "json/JSON.cpp"
#include "logging/FileLogger.cpp"
#include "logging/Logger.cpp"
#include "maths/BigInteger.cpp"
#include "maths/Random.cpp"
#include "memory/MemoryBlock.cpp"
#include "misc/Main.cpp"
#include "misc/Result.cpp"
#include "misc/Uuid.cpp"
#include "network/MACAddress.cpp"
#include "network/Socket.cpp"
#include "streams/BufferedInputStream.cpp"
#include "streams/FileInputSource.cpp"
#include "streams/InputStream.cpp"
#include "streams/MemoryInputStream.cpp"
#include "streams/MemoryOutputStream.cpp"
#include "streams/OutputStream.cpp"
#include "streams/SubregionStream.cpp"
#include "system/SystemStats.cpp"
#include "text/LexicalCast.cpp"
#include "text/Identifier.cpp"
#include "text/LocalisedStrings.cpp"
#include "text/StringArray.cpp"
#include "text/StringPairArray.cpp"
#include "text/StringPool.cpp"
#include "thread/impl/TrackedMutex.cpp"
#include "thread/DeadlineTimer.cpp"
#include "thread/Workers.cpp"
#include "threads/ChildProcess.cpp"
#include "threads/SpinDelay.cpp"
#include "time/PerformanceCounter.cpp"
#include "time/AtExitHook.cpp"
#include "time/Time.cpp"
#include "xml/XmlDocument.cpp"
#include "xml/XmlElement.cpp"
#include "zip/GZIPDecompressorInputStream.cpp"
#include "zip/GZIPCompressorOutputStream.cpp"
#include "zip/ZipFile.cpp"
#if BEAST_MAC || BEAST_IOS
#include "native/osx_ObjCHelpers.h"
#endif
#if BEAST_WINDOWS
#include "native/win32_FPUFlags.cpp"
#else
#include "native/posix_FPUFlags.cpp"
#endif
#if BEAST_ANDROID
#include "native/android_JNIHelpers.h"
#endif

View File

@@ -54,12 +54,15 @@
#include "../../beast/HeapBlock.h"
#include "../../beast/Memory.h"
#include "../../beast/Intrusive.h"
#include "../../beast/Net.h"
#include "../../beast/Strings.h"
#include "../../beast/TypeTraits.h"
#include "../../beast/Threads.h"
#include "../../beast/Utility.h"
#include "../../beast/Chrono.h"
#include "../../beast/utility/Debug.h"
#include "../../beast/utility/Error.h"
#include "../../beast/utility/Journal.h"
#include "../../beast/utility/LeakChecked.h"
#include "../../beast/utility/PropertyStream.h"
#include "../../beast/utility/StaticObject.h"
#include "system/StandardIncludes.h"
@@ -78,7 +81,6 @@ class FileOutputStream;
#include "diagnostic/Throw.h"
#include "system/Functional.h"
#include "threads/SpinDelay.h"
#include "time/AtExitHook.h"
#include "time/Time.h"
@@ -139,30 +141,19 @@ class FileOutputStream;
#include "text/StringArray.h"
#include "memory/MemoryBlock.h"
#include "files/File.h"
#include "time/PerformanceCounter.h"
#include "memory/MemoryAlignment.h"
#include "memory/CacheLine.h"
#include "thread/MutexTraits.h"
#include "thread/TrackedMutex.h"
#include "diagnostic/FatalError.h"
#include "text/LexicalCast.h"
#include "maths/Math.h"
#include "logging/Logger.h"
#include "diagnostic/FPUFlags.h"
#include "text/Identifier.h"
#include "containers/Variant.h"
#include "containers/LinkedListPointer.h"
#include "containers/NamedValueSet.h"
#include "containers/DynamicObject.h"
#include "maths/BigInteger.h"
#include "maths/Random.h"
#include "containers/OwnedArray.h"
#include "text/StringPairArray.h"
#include "containers/PropertySet.h"
#include "containers/ScopedValueSetter.h"
#include "maths/Range.h"
#include "containers/SparseSet.h"
#include "files/DirectoryIterator.h"
#include "streams/InputStream.h"
#include "files/FileInputStream.h"
@@ -171,28 +162,16 @@ class FileOutputStream;
#include "streams/OutputStream.h"
#include "files/FileOutputStream.h"
#include "files/FileSearchPath.h"
#include "files/MemoryMappedFile.h"
#include "files/RandomAccessFile.h"
#include "files/TemporaryFile.h"
#include "json/JSON.h"
#include "logging/FileLogger.h"
#include "logging/Logger.h"
#include "memory/OptionalScopedPointer.h"
#include "memory/SharedSingleton.h"
#include "misc/Main.h"
#include "misc/Uuid.h"
#include "misc/WindowsRegistry.h"
#include "network/MACAddress.h"
#include "network/Socket.h"
#include "streams/BufferedInputStream.h"
#include "streams/MemoryInputStream.h"
#include "streams/MemoryOutputStream.h"
#include "streams/SubregionStream.h"
#include "system/SystemStats.h"
#include "text/LocalisedStrings.h"
#include "diagnostic/SemanticVersion.h"
#include "text/StringPool.h"
#include "threads/ChildProcess.h"
#include "threads/DynamicLibrary.h"
#include "threads/HighResolutionTimer.h"
@@ -202,9 +181,6 @@ class FileOutputStream;
#include "xml/XmlDocument.h"
#include "xml/XmlElement.h"
#include "diagnostic/UnitTestUtilities.h"
#include "zip/GZIPCompressorOutputStream.h"
#include "zip/GZIPDecompressorInputStream.h"
#include "zip/ZipFile.h"
#include "diagnostic/MeasureFunctionCallTime.h"

View File

@@ -1,79 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace beast
{
DynamicObject::DynamicObject()
{
}
DynamicObject::~DynamicObject()
{
}
bool DynamicObject::hasProperty (const Identifier& propertyName) const
{
const var* const v = properties.getVarPointer (propertyName);
return v != nullptr && ! v->isMethod();
}
var DynamicObject::getProperty (const Identifier& propertyName) const
{
return properties [propertyName];
}
void DynamicObject::setProperty (const Identifier& propertyName, const var& newValue)
{
properties.set (propertyName, newValue);
}
void DynamicObject::removeProperty (const Identifier& propertyName)
{
properties.remove (propertyName);
}
bool DynamicObject::hasMethod (const Identifier& methodName) const
{
return getProperty (methodName).isMethod();
}
var DynamicObject::invokeMethod (const Identifier& methodName,
const var* parameters,
int numParameters)
{
return properties [methodName].invokeMethod (this, parameters, numParameters);
}
void DynamicObject::setMethod (const Identifier& name,
var::MethodFunction methodFunction)
{
properties.set (name, var (methodFunction));
}
void DynamicObject::clear()
{
properties.clear();
}
} // namespace beast

View File

@@ -1,120 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_DYNAMICOBJECT_H_INCLUDED
#define BEAST_DYNAMICOBJECT_H_INCLUDED
namespace beast
{
//==============================================================================
/**
Represents a dynamically implemented object.
This class is primarily intended for wrapping scripting language objects,
but could be used for other purposes.
An instance of a DynamicObject can be used to store named properties, and
by subclassing hasMethod() and invokeMethod(), you can give your object
methods.
*/
class BEAST_API DynamicObject
: public SharedObject
, LeakChecked <DynamicObject>
{
public:
//==============================================================================
DynamicObject();
/** Destructor. */
virtual ~DynamicObject();
typedef SharedPtr<DynamicObject> Ptr;
//==============================================================================
/** Returns true if the object has a property with this name.
Note that if the property is actually a method, this will return false.
*/
virtual bool hasProperty (const Identifier& propertyName) const;
/** Returns a named property.
This returns a void if no such property exists.
*/
virtual var getProperty (const Identifier& propertyName) const;
/** Sets a named property. */
virtual void setProperty (const Identifier& propertyName, const var& newValue);
/** Removes a named property. */
virtual void removeProperty (const Identifier& propertyName);
//==============================================================================
/** Checks whether this object has the specified method.
The default implementation of this just checks whether there's a property
with this name that's actually a method, but this can be overridden for
building objects with dynamic invocation.
*/
virtual bool hasMethod (const Identifier& methodName) const;
/** Invokes a named method on this object.
The default implementation looks up the named property, and if it's a method
call, then it invokes it.
This method is virtual to allow more dynamic invocation to used for objects
where the methods may not already be set as properies.
*/
virtual var invokeMethod (const Identifier& methodName,
const var* parameters,
int numParameters);
/** Sets up a method.
This is basically the same as calling setProperty (methodName, (var::MethodFunction) myFunction), but
helps to avoid accidentally invoking the wrong type of var constructor. It also makes
the code easier to read,
The compiler will probably force you to use an explicit cast your method to a (var::MethodFunction), e.g.
@code
setMethod ("doSomething", (var::MethodFunction) &MyClass::doSomething);
@endcode
*/
void setMethod (const Identifier& methodName,
var::MethodFunction methodFunction);
//==============================================================================
/** Removes all properties and methods from the object. */
void clear();
/** Returns the NamedValueSet that holds the object's properties. */
NamedValueSet& getProperties() noexcept { return properties; }
private:
//==============================================================================
NamedValueSet properties;
};
} // namespace beast
#endif // BEAST_DYNAMICOBJECT_H_INCLUDED

View File

@@ -1,211 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_INTRUSIVE_LOCKFREEQUEUE_H_INCLUDED
#define BEAST_INTRUSIVE_LOCKFREEQUEUE_H_INCLUDED
/** Multiple Producer, Single Consumer (MPSC) intrusive FIFO.
This container uses the same intrusive interface as List. It is wait-free
for producers and lock-free for consumers. The caller is responsible for
preventing the ABA problem (http://en.wikipedia.org/wiki/ABA_problem)
Invariants:
- Any thread may call push_back() at any time (Multiple Producer).
- Only one thread may call try_pop_front() at a time (Single Consumer)
- The queue is signaled if there are one or more elements.
@param Tag A type name used to distinguish lists and nodes, for
putting objects in multiple lists. If this parameter is
omitted, the default tag is used.
@ingroup beast_core intrusive
*/
template <class Element, class Tag = void>
class LockFreeQueue
{
public:
class Node : public Uncopyable
{
public:
Node () { }
explicit Node (Node* next) : m_next (next) { }
AtomicPointer <Node> m_next;
};
public:
/** Create an empty list.
*/
LockFreeQueue ()
: m_head (&m_null)
, m_tail (&m_null)
, m_null (nullptr)
{
}
/** Determine if the list is empty.
This is not thread safe, the caller must synchronize.
@return true if the list is empty.
*/
bool empty () const
{
return (m_head.get () == m_tail);
}
/** Put an element into the list.
This operation is wait-free.
@param node The element to enqueue.
@return true if the list was previously empty.
*/
bool push_back (Node* node)
{
node->m_next.set (0);
Node* prev = m_head.exchange (node);
// (*) If a try_pop_front() happens at this point, it might not see the
// element we are pushing. This only happens when the list is empty,
// and furthermore it is detectable.
prev->m_next.set (node);
return prev == &m_null;
}
/** Retrieve an element from the list.
This operation is lock-free.
@return The element, or nullptr if the list was empty.
*/
Element* pop_front ()
{
Element* elem;
// Avoid the SpinDelay ctor if possible
if (!try_pop_front (&elem))
{
SpinDelay delay;
do
{
delay.pause ();
}
while (!try_pop_front (&elem));
}
return elem;
}
/** Attempt to retrieve an element.
This attempts to pop an element from the front of the list. The return
value indicates if the operation was successful. An operation is
successful if there is no contention for the list. On a successful
operation, an element is returned if the list was non empty, else nullptr
is returned. On failure, the returned element is undefined.
This operation is wait-free.
@param[out] pElem The element that was retrieved, or nullptr if the
list was empty.
@return true if the list was uncontended.
*/
bool try_pop_front (Element** pElem)
{
Node* tail = m_tail;
Node* next = tail->m_next.get ();
if (tail == &m_null)
{
if (next == 0)
{
// (*) If a push_back() happens at this point,
// we might not see the element.
if (m_head.get () == tail)
{
*pElem = nullptr;
return true; // success, but queue empty
}
else
{
return false; // failure: a push_back() caused contention
}
}
m_tail = next;
tail = next;
next = next->m_next.get ();
}
if (next)
{
m_tail = next;
*pElem = static_cast <Element*> (tail);
return true;
}
Node* head = m_head.get ();
if (tail == head)
{
push_back (&m_null);
next = tail->m_next.get ();
if (next)
{
m_tail = next;
*pElem = static_cast <Element*> (tail);
return true;
}
}
// (*) If a push_back() happens at this point,
// we might not see the element.
if (head == m_tail)
{
*pElem = nullptr;
return true; // success, but queue empty
}
else
{
return false; // failure: a push_back() caused contention
}
}
private:
// Elements are pushed on to the head and popped from the tail.
AtomicPointer <Node> m_head;
Node* m_tail;
Node m_null;
};
#endif

View File

@@ -1,309 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace beast
{
NamedValueSet::NamedValue::NamedValue() noexcept
{
}
inline NamedValueSet::NamedValue::NamedValue (const Identifier n, const var& v)
: name (n), value (v)
{
}
NamedValueSet::NamedValue::NamedValue (const NamedValue& other)
: name (other.name), value (other.value)
{
}
NamedValueSet::NamedValue& NamedValueSet::NamedValue::operator= (const NamedValueSet::NamedValue& other)
{
name = other.name;
value = other.value;
return *this;
}
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
NamedValueSet::NamedValue::NamedValue (NamedValue&& other) noexcept
: nextListItem (static_cast <LinkedListPointer<NamedValue>&&> (other.nextListItem)),
name (static_cast <Identifier&&> (other.name)),
value (static_cast <var&&> (other.value))
{
}
inline NamedValueSet::NamedValue::NamedValue (const Identifier n, var&& v)
: name (n), value (static_cast <var&&> (v))
{
}
NamedValueSet::NamedValue& NamedValueSet::NamedValue::operator= (NamedValue&& other) noexcept
{
nextListItem = static_cast <LinkedListPointer<NamedValue>&&> (other.nextListItem);
name = static_cast <Identifier&&> (other.name);
value = static_cast <var&&> (other.value);
return *this;
}
#endif
bool NamedValueSet::NamedValue::operator== (const NamedValueSet::NamedValue& other) const noexcept
{
return name == other.name && value == other.value;
}
//==============================================================================
NamedValueSet::NamedValueSet() noexcept
{
}
NamedValueSet::NamedValueSet (const NamedValueSet& other)
{
values.addCopyOfList (other.values);
}
NamedValueSet& NamedValueSet::operator= (const NamedValueSet& other)
{
clear();
values.addCopyOfList (other.values);
return *this;
}
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
NamedValueSet::NamedValueSet (NamedValueSet&& other) noexcept
: values (static_cast <LinkedListPointer<NamedValue>&&> (other.values))
{
}
NamedValueSet& NamedValueSet::operator= (NamedValueSet&& other) noexcept
{
other.values.swapWith (values);
return *this;
}
#endif
NamedValueSet::~NamedValueSet()
{
clear();
}
void NamedValueSet::clear()
{
values.deleteAll();
}
bool NamedValueSet::operator== (const NamedValueSet& other) const
{
const NamedValue* i1 = values;
const NamedValue* i2 = other.values;
while (i1 != nullptr && i2 != nullptr)
{
if (! (*i1 == *i2))
return false;
i1 = i1->nextListItem;
i2 = i2->nextListItem;
}
return true;
}
bool NamedValueSet::operator!= (const NamedValueSet& other) const
{
return ! operator== (other);
}
int NamedValueSet::size() const noexcept
{
return values.size();
}
const var& NamedValueSet::operator[] (const Identifier name) const
{
for (NamedValue* i = values; i != nullptr; i = i->nextListItem)
if (i->name == name)
return i->value;
return var::null;
}
var NamedValueSet::getWithDefault (const Identifier name, const var& defaultReturnValue) const
{
if (const var* const v = getVarPointer (name))
return *v;
return defaultReturnValue;
}
var* NamedValueSet::getVarPointer (const Identifier name) const noexcept
{
for (NamedValue* i = values; i != nullptr; i = i->nextListItem)
if (i->name == name)
return &(i->value);
return nullptr;
}
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
bool NamedValueSet::set (const Identifier name, var&& newValue)
{
LinkedListPointer<NamedValue>* i = &values;
while (i->get() != nullptr)
{
NamedValue* const v = i->get();
if (v->name == name)
{
if (v->value.equalsWithSameType (newValue))
return false;
v->value = static_cast <var&&> (newValue);
return true;
}
i = &(v->nextListItem);
}
i->insertNext (new NamedValue (name, static_cast <var&&> (newValue)));
return true;
}
#endif
bool NamedValueSet::set (const Identifier name, const var& newValue)
{
LinkedListPointer<NamedValue>* i = &values;
while (i->get() != nullptr)
{
NamedValue* const v = i->get();
if (v->name == name)
{
if (v->value.equalsWithSameType (newValue))
return false;
v->value = newValue;
return true;
}
i = &(v->nextListItem);
}
i->insertNext (new NamedValue (name, newValue));
return true;
}
bool NamedValueSet::contains (const Identifier name) const
{
return getVarPointer (name) != nullptr;
}
bool NamedValueSet::remove (const Identifier name)
{
LinkedListPointer<NamedValue>* i = &values;
for (;;)
{
NamedValue* const v = i->get();
if (v == nullptr)
break;
if (v->name == name)
{
delete i->removeNext();
return true;
}
i = &(v->nextListItem);
}
return false;
}
const Identifier NamedValueSet::getName (const int index) const
{
const NamedValue* const v = values[index];
bassert (v != nullptr);
return v->name;
}
const var& NamedValueSet::getValueAt (const int index) const
{
const NamedValue* const v = values[index];
bassert (v != nullptr);
return v->value;
}
void NamedValueSet::setFromXmlAttributes (const XmlElement& xml)
{
clear();
LinkedListPointer<NamedValue>::Appender appender (values);
const int numAtts = xml.getNumAttributes(); // xxx inefficient - should write an att iterator..
for (int i = 0; i < numAtts; ++i)
{
const String& name = xml.getAttributeName (i);
const String& value = xml.getAttributeValue (i);
if (name.startsWith ("base64:"))
{
MemoryBlock mb;
if (mb.fromBase64Encoding (value))
{
appender.append (new NamedValue (name.substring (7), var (mb)));
continue;
}
}
appender.append (new NamedValue (name, var (value)));
}
}
void NamedValueSet::copyToXmlAttributes (XmlElement& xml) const
{
for (NamedValue* i = values; i != nullptr; i = i->nextListItem)
{
if (const MemoryBlock* mb = i->value.getBinaryData())
{
xml.setAttribute ("base64:" + i->name.toString(),
mb->toBase64Encoding());
}
else
{
// These types can't be stored as XML!
bassert (! i->value.isObject());
bassert (! i->value.isMethod());
bassert (! i->value.isArray());
xml.setAttribute (i->name.toString(),
i->value.toString());
}
}
}
} // namespace beast

View File

@@ -1,165 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_NAMEDVALUESET_H_INCLUDED
#define BEAST_NAMEDVALUESET_H_INCLUDED
namespace beast
{
class XmlElement;
#ifndef DOXYGEN
class JSONFormatter;
#endif
//==============================================================================
/** Holds a set of named var objects.
This can be used as a basic structure to hold a set of var object, which can
be retrieved by using their identifier.
*/
class BEAST_API NamedValueSet
{
public:
/** Creates an empty set. */
NamedValueSet() noexcept;
/** Creates a copy of another set. */
NamedValueSet (const NamedValueSet& other);
/** Replaces this set with a copy of another set. */
NamedValueSet& operator= (const NamedValueSet& other);
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
NamedValueSet (NamedValueSet&& other) noexcept;
NamedValueSet& operator= (NamedValueSet&& other) noexcept;
#endif
/** Destructor. */
~NamedValueSet();
bool operator== (const NamedValueSet& other) const;
bool operator!= (const NamedValueSet& other) const;
//==============================================================================
/** Returns the total number of values that the set contains. */
int size() const noexcept;
/** Returns the value of a named item.
If the name isn't found, this will return a void variant.
@see getProperty
*/
const var& operator[] (const Identifier name) const;
/** Tries to return the named value, but if no such value is found, this will
instead return the supplied default value.
*/
var getWithDefault (const Identifier name, const var& defaultReturnValue) const;
/** Changes or adds a named value.
@returns true if a value was changed or added; false if the
value was already set the the value passed-in.
*/
bool set (const Identifier name, const var& newValue);
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
/** Changes or adds a named value.
@returns true if a value was changed or added; false if the
value was already set the the value passed-in.
*/
bool set (const Identifier name, var&& newValue);
#endif
/** Returns true if the set contains an item with the specified name. */
bool contains (const Identifier name) const;
/** Removes a value from the set.
@returns true if a value was removed; false if there was no value
with the name that was given.
*/
bool remove (const Identifier name);
/** Returns the name of the value at a given index.
The index must be between 0 and size() - 1.
*/
const Identifier getName (int index) const;
/** Returns the value of the item at a given index.
The index must be between 0 and size() - 1.
*/
const var& getValueAt (int index) const;
/** Removes all values. */
void clear();
//==============================================================================
/** Returns a pointer to the var that holds a named value, or null if there is
no value with this name.
Do not use this method unless you really need access to the internal var object
for some reason - for normal reading and writing always prefer operator[]() and set().
*/
var* getVarPointer (const Identifier name) const noexcept;
//==============================================================================
/** Sets properties to the values of all of an XML element's attributes. */
void setFromXmlAttributes (const XmlElement& xml);
/** Sets attributes in an XML element corresponding to each of this object's
properties.
*/
void copyToXmlAttributes (XmlElement& xml) const;
private:
//==============================================================================
class NamedValue : LeakChecked <NamedValue>
{
public:
NamedValue() noexcept;
NamedValue (const NamedValue&);
NamedValue (const Identifier name, const var& value);
NamedValue& operator= (const NamedValue&);
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
NamedValue (NamedValue&&) noexcept;
NamedValue (const Identifier name, var&& value);
NamedValue& operator= (NamedValue&&) noexcept;
#endif
bool operator== (const NamedValue& other) const noexcept;
LinkedListPointer<NamedValue> nextListItem;
Identifier name;
var value;
private:
};
friend class LinkedListPointer<NamedValue>;
LinkedListPointer<NamedValue> values;
friend class JSONFormatter;
};
} // namespace beast
#endif // BEAST_NAMEDVALUESET_H_INCLUDED

View File

@@ -1,223 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace beast
{
PropertySet::PropertySet (const bool ignoreCaseOfKeyNames)
: properties (ignoreCaseOfKeyNames),
fallbackProperties (nullptr),
ignoreCaseOfKeys (ignoreCaseOfKeyNames)
{
}
PropertySet::PropertySet (const PropertySet& other)
: properties (other.properties),
fallbackProperties (other.fallbackProperties),
ignoreCaseOfKeys (other.ignoreCaseOfKeys)
{
}
PropertySet& PropertySet::operator= (const PropertySet& other)
{
properties = other.properties;
fallbackProperties = other.fallbackProperties;
ignoreCaseOfKeys = other.ignoreCaseOfKeys;
propertyChanged();
return *this;
}
PropertySet::~PropertySet()
{
}
void PropertySet::clear()
{
const ScopedLock sl (lock);
if (properties.size() > 0)
{
properties.clear();
propertyChanged();
}
}
String PropertySet::getValue (const String& keyName,
const String& defaultValue) const noexcept
{
const ScopedLock sl (lock);
const int index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys);
if (index >= 0)
return properties.getAllValues() [index];
return fallbackProperties != nullptr ? fallbackProperties->getValue (keyName, defaultValue)
: defaultValue;
}
int PropertySet::getIntValue (const String& keyName,
const int defaultValue) const noexcept
{
const ScopedLock sl (lock);
const int index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys);
if (index >= 0)
return properties.getAllValues() [index].getIntValue();
return fallbackProperties != nullptr ? fallbackProperties->getIntValue (keyName, defaultValue)
: defaultValue;
}
double PropertySet::getDoubleValue (const String& keyName,
const double defaultValue) const noexcept
{
const ScopedLock sl (lock);
const int index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys);
if (index >= 0)
return properties.getAllValues()[index].getDoubleValue();
return fallbackProperties != nullptr ? fallbackProperties->getDoubleValue (keyName, defaultValue)
: defaultValue;
}
bool PropertySet::getBoolValue (const String& keyName,
const bool defaultValue) const noexcept
{
const ScopedLock sl (lock);
const int index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys);
if (index >= 0)
return properties.getAllValues() [index].getIntValue() != 0;
return fallbackProperties != nullptr ? fallbackProperties->getBoolValue (keyName, defaultValue)
: defaultValue;
}
XmlElement* PropertySet::getXmlValue (const String& keyName) const
{
return XmlDocument::parse (getValue (keyName));
}
void PropertySet::setValue (const String& keyName, const var& v)
{
bassert (keyName.isNotEmpty()); // shouldn't use an empty key name!
if (keyName.isNotEmpty())
{
const String value (v.toString());
const ScopedLock sl (lock);
const int index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys);
if (index < 0 || properties.getAllValues() [index] != value)
{
properties.set (keyName, value);
propertyChanged();
}
}
}
void PropertySet::removeValue (const String& keyName)
{
if (keyName.isNotEmpty())
{
const ScopedLock sl (lock);
const int index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys);
if (index >= 0)
{
properties.remove (keyName);
propertyChanged();
}
}
}
void PropertySet::setValue (const String& keyName, const XmlElement* const xml)
{
setValue (keyName, xml == nullptr ? var::null
: var (xml->createDocument (String::empty, true)));
}
bool PropertySet::containsKey (const String& keyName) const noexcept
{
const ScopedLock sl (lock);
return properties.getAllKeys().contains (keyName, ignoreCaseOfKeys);
}
void PropertySet::addAllPropertiesFrom (const PropertySet& source)
{
const ScopedLock sl (source.getLock());
for (int i = 0; i < source.properties.size(); ++i)
setValue (source.properties.getAllKeys() [i],
source.properties.getAllValues() [i]);
}
void PropertySet::setFallbackPropertySet (PropertySet* fallbackProperties_) noexcept
{
const ScopedLock sl (lock);
fallbackProperties = fallbackProperties_;
}
XmlElement* PropertySet::createXml (const String& nodeName) const
{
const ScopedLock sl (lock);
XmlElement* const xml = new XmlElement (nodeName);
for (int i = 0; i < properties.getAllKeys().size(); ++i)
{
XmlElement* const e = xml->createNewChildElement ("VALUE");
e->setAttribute ("name", properties.getAllKeys()[i]);
e->setAttribute ("val", properties.getAllValues()[i]);
}
return xml;
}
void PropertySet::restoreFromXml (const XmlElement& xml)
{
const ScopedLock sl (lock);
clear();
beast_forEachXmlChildElementWithTagName (xml, e, "VALUE")
{
if (e->hasAttribute ("name")
&& e->hasAttribute ("val"))
{
properties.set (e->getStringAttribute ("name"),
e->getStringAttribute ("val"));
}
}
if (properties.size() > 0)
propertyChanged();
}
void PropertySet::propertyChanged()
{
}
} // namespace beast

View File

@@ -1,211 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_PROPERTYSET_H_INCLUDED
#define BEAST_PROPERTYSET_H_INCLUDED
namespace beast
{
//==============================================================================
/**
A set of named property values, which can be strings, integers, floating point, etc.
Effectively, this just wraps a StringPairArray in an interface that makes it easier
to load and save types other than strings.
See the PropertiesFile class for a subclass of this, which automatically broadcasts change
messages and saves/loads the list from a file.
*/
class BEAST_API PropertySet : LeakChecked <PropertySet>
{
public:
//==============================================================================
/** Creates an empty PropertySet.
@param ignoreCaseOfKeyNames if true, the names of properties are compared in a
case-insensitive way
*/
PropertySet (bool ignoreCaseOfKeyNames = false);
/** Creates a copy of another PropertySet. */
PropertySet (const PropertySet& other);
/** Copies another PropertySet over this one. */
PropertySet& operator= (const PropertySet& other);
/** Destructor. */
virtual ~PropertySet();
//==============================================================================
/** Returns one of the properties as a string.
If the value isn't found in this set, then this will look for it in a fallback
property set (if you've specified one with the setFallbackPropertySet() method),
and if it can't find one there, it'll return the default value passed-in.
@param keyName the name of the property to retrieve
@param defaultReturnValue a value to return if the named property doesn't actually exist
*/
String getValue (const String& keyName,
const String& defaultReturnValue = String::empty) const noexcept;
/** Returns one of the properties as an integer.
If the value isn't found in this set, then this will look for it in a fallback
property set (if you've specified one with the setFallbackPropertySet() method),
and if it can't find one there, it'll return the default value passed-in.
@param keyName the name of the property to retrieve
@param defaultReturnValue a value to return if the named property doesn't actually exist
*/
int getIntValue (const String& keyName,
const int defaultReturnValue = 0) const noexcept;
/** Returns one of the properties as an double.
If the value isn't found in this set, then this will look for it in a fallback
property set (if you've specified one with the setFallbackPropertySet() method),
and if it can't find one there, it'll return the default value passed-in.
@param keyName the name of the property to retrieve
@param defaultReturnValue a value to return if the named property doesn't actually exist
*/
double getDoubleValue (const String& keyName,
const double defaultReturnValue = 0.0) const noexcept;
/** Returns one of the properties as an boolean.
The result will be true if the string found for this key name can be parsed as a non-zero
integer.
If the value isn't found in this set, then this will look for it in a fallback
property set (if you've specified one with the setFallbackPropertySet() method),
and if it can't find one there, it'll return the default value passed-in.
@param keyName the name of the property to retrieve
@param defaultReturnValue a value to return if the named property doesn't actually exist
*/
bool getBoolValue (const String& keyName,
const bool defaultReturnValue = false) const noexcept;
/** Returns one of the properties as an XML element.
The result will a new XMLElement object that the caller must delete. If may return 0 if the
key isn't found, or if the entry contains an string that isn't valid XML.
If the value isn't found in this set, then this will look for it in a fallback
property set (if you've specified one with the setFallbackPropertySet() method),
and if it can't find one there, it'll return the default value passed-in.
@param keyName the name of the property to retrieve
*/
XmlElement* getXmlValue (const String& keyName) const;
//==============================================================================
/** Sets a named property.
@param keyName the name of the property to set. (This mustn't be an empty string)
@param value the new value to set it to
*/
void setValue (const String& keyName, const var& value);
/** Sets a named property to an XML element.
@param keyName the name of the property to set. (This mustn't be an empty string)
@param xml the new element to set it to. If this is zero, the value will be set to
an empty string
@see getXmlValue
*/
void setValue (const String& keyName, const XmlElement* xml);
/** This copies all the values from a source PropertySet to this one.
This won't remove any existing settings, it just adds any that it finds in the source set.
*/
void addAllPropertiesFrom (const PropertySet& source);
//==============================================================================
/** Deletes a property.
@param keyName the name of the property to delete. (This mustn't be an empty string)
*/
void removeValue (const String& keyName);
/** Returns true if the properies include the given key. */
bool containsKey (const String& keyName) const noexcept;
/** Removes all values. */
void clear();
//==============================================================================
/** Returns the keys/value pair array containing all the properties. */
StringPairArray& getAllProperties() noexcept { return properties; }
/** Returns the lock used when reading or writing to this set */
const CriticalSection& getLock() const noexcept { return lock; }
//==============================================================================
/** Returns an XML element which encapsulates all the items in this property set.
The string parameter is the tag name that should be used for the node.
@see restoreFromXml
*/
XmlElement* createXml (const String& nodeName) const;
/** Reloads a set of properties that were previously stored as XML.
The node passed in must have been created by the createXml() method.
@see createXml
*/
void restoreFromXml (const XmlElement& xml);
//==============================================================================
/** Sets up a second PopertySet that will be used to look up any values that aren't
set in this one.
If you set this up to be a pointer to a second property set, then whenever one
of the getValue() methods fails to find an entry in this set, it will look up that
value in the fallback set, and if it finds it, it will return that.
Make sure that you don't delete the fallback set while it's still being used by
another set! To remove the fallback set, just call this method with a null pointer.
@see getFallbackPropertySet
*/
void setFallbackPropertySet (PropertySet* fallbackProperties) noexcept;
/** Returns the fallback property set.
@see setFallbackPropertySet
*/
PropertySet* getFallbackPropertySet() const noexcept { return fallbackProperties; }
protected:
/** Subclasses can override this to be told when one of the properies has been changed. */
virtual void propertyChanged();
private:
StringPairArray properties;
PropertySet* fallbackProperties;
CriticalSection lock;
bool ignoreCaseOfKeys;
};
} // namespace beast
#endif // BEAST_PROPERTYSET_H_INCLUDED

View File

@@ -1,295 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_SPARSESET_H_INCLUDED
#define BEAST_SPARSESET_H_INCLUDED
namespace beast
{
//==============================================================================
/**
Holds a set of primitive values, storing them as a set of ranges.
This container acts like an array, but can efficiently hold large contiguous
ranges of values. It's quite a specialised class, mostly useful for things
like keeping the set of selected rows in a listbox.
The type used as a template paramter must be an integer type, such as int, short,
int64, etc.
*/
template <class Type>
class SparseSet
{
public:
//==============================================================================
/** Creates a new empty set. */
SparseSet()
{
}
/** Creates a copy of another SparseSet. */
SparseSet (const SparseSet<Type>& other)
: values (other.values)
{
}
//==============================================================================
/** Clears the set. */
void clear()
{
values.clear();
}
/** Checks whether the set is empty.
This is much quicker than using (size() == 0).
*/
bool isEmpty() const noexcept
{
return values.size() == 0;
}
/** Returns the number of values in the set.
Because of the way the data is stored, this method can take longer if there
are a lot of items in the set. Use isEmpty() for a quick test of whether there
are any items.
*/
Type size() const
{
Type total (0);
for (int i = 0; i < values.size(); i += 2)
total += values.getUnchecked (i + 1) - values.getUnchecked (i);
return total;
}
/** Returns one of the values in the set.
@param index the index of the value to retrieve, in the range 0 to (size() - 1).
@returns the value at this index, or 0 if it's out-of-range
*/
Type operator[] (Type index) const
{
for (int i = 0; i < values.size(); i += 2)
{
const Type start (values.getUnchecked (i));
const Type len (values.getUnchecked (i + 1) - start);
if (index < len)
return start + index;
index -= len;
}
return Type();
}
/** Checks whether a particular value is in the set. */
bool contains (const Type valueToLookFor) const
{
for (int i = 0; i < values.size(); ++i)
if (valueToLookFor < values.getUnchecked(i))
return (i & 1) != 0;
return false;
}
//==============================================================================
/** Returns the number of contiguous blocks of values.
@see getRange
*/
int getNumRanges() const noexcept
{
return values.size() >> 1;
}
/** Returns one of the contiguous ranges of values stored.
@param rangeIndex the index of the range to look up, between 0
and (getNumRanges() - 1)
@see getTotalRange
*/
const Range<Type> getRange (const int rangeIndex) const
{
if (isPositiveAndBelow (rangeIndex, getNumRanges()))
return Range<Type> (values.getUnchecked (rangeIndex << 1),
values.getUnchecked ((rangeIndex << 1) + 1));
return Range<Type>();
}
/** Returns the range between the lowest and highest values in the set.
@see getRange
*/
Range<Type> getTotalRange() const
{
if (values.size() > 0)
{
bassert ((values.size() & 1) == 0);
return Range<Type> (values.getUnchecked (0),
values.getUnchecked (values.size() - 1));
}
return Range<Type>();
}
//==============================================================================
/** Adds a range of contiguous values to the set.
e.g. addRange (Range \<int\> (10, 14)) will add (10, 11, 12, 13) to the set.
*/
void addRange (const Range<Type> range)
{
bassert (range.getLength() >= 0);
if (range.getLength() > 0)
{
removeRange (range);
values.addUsingDefaultSort (range.getStart());
values.addUsingDefaultSort (range.getEnd());
simplify();
}
}
/** Removes a range of values from the set.
e.g. removeRange (Range\<int\> (10, 14)) will remove (10, 11, 12, 13) from the set.
*/
void removeRange (const Range<Type> rangeToRemove)
{
bassert (rangeToRemove.getLength() >= 0);
if (rangeToRemove.getLength() > 0
&& values.size() > 0
&& rangeToRemove.getStart() < values.getUnchecked (values.size() - 1)
&& values.getUnchecked(0) < rangeToRemove.getEnd())
{
const bool onAtStart = contains (rangeToRemove.getStart() - 1);
const Type lastValue (bmin (rangeToRemove.getEnd(), values.getLast()));
const bool onAtEnd = contains (lastValue);
for (int i = values.size(); --i >= 0;)
{
if (values.getUnchecked(i) <= lastValue)
{
while (values.getUnchecked(i) >= rangeToRemove.getStart())
{
values.remove (i);
if (--i < 0)
break;
}
break;
}
}
if (onAtStart) values.addUsingDefaultSort (rangeToRemove.getStart());
if (onAtEnd) values.addUsingDefaultSort (lastValue);
simplify();
}
}
/** Does an XOR of the values in a given range. */
void invertRange (const Range<Type> range)
{
SparseSet newItems;
newItems.addRange (range);
for (int i = getNumRanges(); --i >= 0;)
newItems.removeRange (getRange (i));
removeRange (range);
for (int i = newItems.getNumRanges(); --i >= 0;)
addRange (newItems.getRange(i));
}
/** Checks whether any part of a given range overlaps any part of this set. */
bool overlapsRange (const Range<Type> range)
{
if (range.getLength() > 0)
{
for (int i = getNumRanges(); --i >= 0;)
{
if (values.getUnchecked ((i << 1) + 1) <= range.getStart())
return false;
if (values.getUnchecked (i << 1) < range.getEnd())
return true;
}
}
return false;
}
/** Checks whether the whole of a given range is contained within this one. */
bool containsRange (const Range<Type> range)
{
if (range.getLength() > 0)
{
for (int i = getNumRanges(); --i >= 0;)
{
if (values.getUnchecked ((i << 1) + 1) <= range.getStart())
return false;
if (values.getUnchecked (i << 1) <= range.getStart()
&& range.getEnd() <= values.getUnchecked ((i << 1) + 1))
return true;
}
}
return false;
}
//==============================================================================
bool operator== (const SparseSet<Type>& other) noexcept
{
return values == other.values;
}
bool operator!= (const SparseSet<Type>& other) noexcept
{
return values != other.values;
}
private:
//==============================================================================
// alternating start/end values of ranges of values that are present.
Array<Type, DummyCriticalSection> values;
void simplify()
{
bassert ((values.size() & 1) == 0);
for (int i = values.size(); --i > 0;)
if (values.getUnchecked(i) == values.getUnchecked (i - 1))
values.removeRange (--i, 2);
}
};
} // namespace beast
#endif // BEAST_SPARSESET_H_INCLUDED

View File

@@ -1,709 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace beast
{
enum VariantStreamMarkers
{
varMarker_Int = 1,
varMarker_BoolTrue = 2,
varMarker_BoolFalse = 3,
varMarker_Double = 4,
varMarker_String = 5,
varMarker_Int64 = 6,
varMarker_Array = 7,
varMarker_Binary = 8
};
//==============================================================================
class var::VariantType
{
public:
VariantType() noexcept {}
virtual ~VariantType() noexcept {}
virtual int toInt (const ValueUnion&) const noexcept { return 0; }
virtual int64 toInt64 (const ValueUnion&) const noexcept { return 0; }
virtual double toDouble (const ValueUnion&) const noexcept { return 0; }
virtual String toString (const ValueUnion&) const { return String::empty; }
virtual bool toBool (const ValueUnion&) const noexcept { return false; }
virtual SharedObject* toObject (const ValueUnion&) const noexcept { return nullptr; }
virtual Array<var>* toArray (const ValueUnion&) const noexcept { return nullptr; }
virtual MemoryBlock* toBinary (const ValueUnion&) const noexcept { return nullptr; }
virtual bool isVoid() const noexcept { return false; }
virtual bool isInt() const noexcept { return false; }
virtual bool isInt64() const noexcept { return false; }
virtual bool isBool() const noexcept { return false; }
virtual bool isDouble() const noexcept { return false; }
virtual bool isString() const noexcept { return false; }
virtual bool isObject() const noexcept { return false; }
virtual bool isArray() const noexcept { return false; }
virtual bool isBinary() const noexcept { return false; }
virtual bool isMethod() const noexcept { return false; }
virtual void cleanUp (ValueUnion&) const noexcept {}
virtual void createCopy (ValueUnion& dest, const ValueUnion& source) const { dest = source; }
virtual bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept = 0;
virtual void writeToStream (const ValueUnion& data, OutputStream& output) const = 0;
};
//==============================================================================
class var::VariantType_Void : public var::VariantType
{
public:
VariantType_Void() noexcept {}
static const VariantType_Void instance;
bool isVoid() const noexcept { return true; }
bool equals (const ValueUnion&, const ValueUnion&, const VariantType& otherType) const noexcept { return otherType.isVoid(); }
void writeToStream (const ValueUnion&, OutputStream& output) const { output.writeCompressedInt (0); }
};
//==============================================================================
class var::VariantType_Int : public var::VariantType
{
public:
VariantType_Int() noexcept {}
static const VariantType_Int instance;
int toInt (const ValueUnion& data) const noexcept { return data.intValue; };
int64 toInt64 (const ValueUnion& data) const noexcept { return (int64) data.intValue; };
double toDouble (const ValueUnion& data) const noexcept { return (double) data.intValue; }
String toString (const ValueUnion& data) const { return String (data.intValue); }
bool toBool (const ValueUnion& data) const noexcept { return data.intValue != 0; }
bool isInt() const noexcept { return true; }
bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept
{
return otherType.toInt (otherData) == data.intValue;
}
void writeToStream (const ValueUnion& data, OutputStream& output) const
{
output.writeCompressedInt (5);
output.writeByte (varMarker_Int);
output.writeInt (data.intValue);
}
};
//==============================================================================
class var::VariantType_Int64 : public var::VariantType
{
public:
VariantType_Int64() noexcept {}
static const VariantType_Int64 instance;
int toInt (const ValueUnion& data) const noexcept { return (int) data.int64Value; };
int64 toInt64 (const ValueUnion& data) const noexcept { return data.int64Value; };
double toDouble (const ValueUnion& data) const noexcept { return (double) data.int64Value; }
String toString (const ValueUnion& data) const { return String (data.int64Value); }
bool toBool (const ValueUnion& data) const noexcept { return data.int64Value != 0; }
bool isInt64() const noexcept { return true; }
bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept
{
return otherType.toInt64 (otherData) == data.int64Value;
}
void writeToStream (const ValueUnion& data, OutputStream& output) const
{
output.writeCompressedInt (9);
output.writeByte (varMarker_Int64);
output.writeInt64 (data.int64Value);
}
};
//==============================================================================
class var::VariantType_Double : public var::VariantType
{
public:
VariantType_Double() noexcept {}
static const VariantType_Double instance;
int toInt (const ValueUnion& data) const noexcept { return (int) data.doubleValue; };
int64 toInt64 (const ValueUnion& data) const noexcept { return (int64) data.doubleValue; };
double toDouble (const ValueUnion& data) const noexcept { return data.doubleValue; }
String toString (const ValueUnion& data) const { return String (data.doubleValue); }
bool toBool (const ValueUnion& data) const noexcept { return data.doubleValue != 0; }
bool isDouble() const noexcept { return true; }
bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept
{
return std::abs (otherType.toDouble (otherData) - data.doubleValue) < std::numeric_limits<double>::epsilon();
}
void writeToStream (const ValueUnion& data, OutputStream& output) const
{
output.writeCompressedInt (9);
output.writeByte (varMarker_Double);
output.writeDouble (data.doubleValue);
}
};
//==============================================================================
class var::VariantType_Bool : public var::VariantType
{
public:
VariantType_Bool() noexcept {}
static const VariantType_Bool instance;
int toInt (const ValueUnion& data) const noexcept { return data.boolValue ? 1 : 0; };
int64 toInt64 (const ValueUnion& data) const noexcept { return data.boolValue ? 1 : 0; };
double toDouble (const ValueUnion& data) const noexcept { return data.boolValue ? 1.0 : 0.0; }
String toString (const ValueUnion& data) const { return String::charToString (data.boolValue ? (beast_wchar) '1' : (beast_wchar) '0'); }
bool toBool (const ValueUnion& data) const noexcept { return data.boolValue; }
bool isBool() const noexcept { return true; }
bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept
{
return otherType.toBool (otherData) == data.boolValue;
}
void writeToStream (const ValueUnion& data, OutputStream& output) const
{
output.writeCompressedInt (1);
output.writeByte (data.boolValue ? (char) varMarker_BoolTrue : (char) varMarker_BoolFalse);
}
};
//==============================================================================
class var::VariantType_String : public var::VariantType
{
public:
VariantType_String() noexcept {}
static const VariantType_String instance;
void cleanUp (ValueUnion& data) const noexcept { getString (data)-> ~String(); }
void createCopy (ValueUnion& dest, const ValueUnion& source) const { new (dest.stringValue) String (*getString (source)); }
bool isString() const noexcept { return true; }
int toInt (const ValueUnion& data) const noexcept { return getString (data)->getIntValue(); };
int64 toInt64 (const ValueUnion& data) const noexcept { return getString (data)->getLargeIntValue(); };
double toDouble (const ValueUnion& data) const noexcept { return getString (data)->getDoubleValue(); }
String toString (const ValueUnion& data) const { return *getString (data); }
bool toBool (const ValueUnion& data) const noexcept { return getString (data)->getIntValue() != 0
|| getString (data)->trim().equalsIgnoreCase ("true")
|| getString (data)->trim().equalsIgnoreCase ("yes"); }
bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept
{
return otherType.toString (otherData) == *getString (data);
}
void writeToStream (const ValueUnion& data, OutputStream& output) const
{
const String* const s = getString (data);
const size_t len = s->getNumBytesAsUTF8() + 1;
HeapBlock<char> temp (len);
s->copyToUTF8 (temp, len);
output.writeCompressedInt ((int) (len + 1));
output.writeByte (varMarker_String);
output.write (temp, len);
}
private:
static inline const String* getString (const ValueUnion& data) noexcept { return reinterpret_cast <const String*> (data.stringValue); }
static inline String* getString (ValueUnion& data) noexcept { return reinterpret_cast <String*> (data.stringValue); }
};
//==============================================================================
class var::VariantType_Object : public var::VariantType
{
public:
VariantType_Object() noexcept {}
static const VariantType_Object instance;
void cleanUp (ValueUnion& data) const noexcept { if (data.objectValue != nullptr) data.objectValue->decReferenceCount(); }
void createCopy (ValueUnion& dest, const ValueUnion& source) const
{
dest.objectValue = source.objectValue;
if (dest.objectValue != nullptr)
dest.objectValue->incReferenceCount();
}
String toString (const ValueUnion& data) const { return "Object 0x" + String::toHexString ((int) (pointer_sized_int) data.objectValue); }
bool toBool (const ValueUnion& data) const noexcept { return data.objectValue != 0; }
SharedObject* toObject (const ValueUnion& data) const noexcept { return data.objectValue; }
bool isObject() const noexcept { return true; }
bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept
{
return otherType.toObject (otherData) == data.objectValue;
}
void writeToStream (const ValueUnion&, OutputStream& output) const
{
bassertfalse; // Can't write an object to a stream!
output.writeCompressedInt (0);
}
};
//==============================================================================
class var::VariantType_Array : public var::VariantType
{
public:
VariantType_Array() noexcept {}
static const VariantType_Array instance;
void cleanUp (ValueUnion& data) const noexcept { delete data.arrayValue; }
void createCopy (ValueUnion& dest, const ValueUnion& source) const { dest.arrayValue = new Array<var> (*(source.arrayValue)); }
String toString (const ValueUnion&) const { return "[Array]"; }
bool isArray() const noexcept { return true; }
Array<var>* toArray (const ValueUnion& data) const noexcept { return data.arrayValue; }
bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept
{
const Array<var>* const otherArray = otherType.toArray (otherData);
return otherArray != nullptr && *otherArray == *(data.arrayValue);
}
void writeToStream (const ValueUnion& data, OutputStream& output) const
{
MemoryOutputStream buffer (512);
const int numItems = data.arrayValue->size();
buffer.writeCompressedInt (numItems);
for (int i = 0; i < numItems; ++i)
data.arrayValue->getReference(i).writeToStream (buffer);
output.writeCompressedInt (1 + (int) buffer.getDataSize());
output.writeByte (varMarker_Array);
output << buffer;
}
};
//==============================================================================
class var::VariantType_Binary : public var::VariantType
{
public:
VariantType_Binary() noexcept {}
static const VariantType_Binary instance;
void cleanUp (ValueUnion& data) const noexcept { delete data.binaryValue; }
void createCopy (ValueUnion& dest, const ValueUnion& source) const { dest.binaryValue = new MemoryBlock (*source.binaryValue); }
String toString (const ValueUnion& data) const { return data.binaryValue->toBase64Encoding(); }
bool isBinary() const noexcept { return true; }
MemoryBlock* toBinary (const ValueUnion& data) const noexcept { return data.binaryValue; }
bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept
{
const MemoryBlock* const otherBlock = otherType.toBinary (otherData);
return otherBlock != nullptr && *otherBlock == *data.binaryValue;
}
void writeToStream (const ValueUnion& data, OutputStream& output) const
{
output.writeCompressedInt (1 + (int) data.binaryValue->getSize());
output.writeByte (varMarker_Binary);
output << *data.binaryValue;
}
};
//==============================================================================
class var::VariantType_Method : public var::VariantType
{
public:
VariantType_Method() noexcept {}
static const VariantType_Method instance;
String toString (const ValueUnion&) const { return "Method"; }
bool toBool (const ValueUnion& data) const noexcept { return data.methodValue != nullptr; }
bool isMethod() const noexcept { return true; }
bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept
{
return otherType.isMethod() && otherData.methodValue == data.methodValue;
}
void writeToStream (const ValueUnion&, OutputStream& output) const
{
bassertfalse; // Can't write a method to a stream!
output.writeCompressedInt (0);
}
};
//==============================================================================
const var::VariantType_Void var::VariantType_Void::instance;
const var::VariantType_Int var::VariantType_Int::instance;
const var::VariantType_Int64 var::VariantType_Int64::instance;
const var::VariantType_Bool var::VariantType_Bool::instance;
const var::VariantType_Double var::VariantType_Double::instance;
const var::VariantType_String var::VariantType_String::instance;
const var::VariantType_Object var::VariantType_Object::instance;
const var::VariantType_Array var::VariantType_Array::instance;
const var::VariantType_Binary var::VariantType_Binary::instance;
const var::VariantType_Method var::VariantType_Method::instance;
//==============================================================================
var::var() noexcept : type (&VariantType_Void::instance)
{
}
var::~var() noexcept
{
type->cleanUp (value);
}
const var var::null;
//==============================================================================
var::var (const var& valueToCopy) : type (valueToCopy.type)
{
type->createCopy (value, valueToCopy.value);
}
var::var (const int v) noexcept : type (&VariantType_Int::instance) { value.intValue = v; }
var::var (const int64 v) noexcept : type (&VariantType_Int64::instance) { value.int64Value = v; }
var::var (const bool v) noexcept : type (&VariantType_Bool::instance) { value.boolValue = v; }
var::var (const double v) noexcept : type (&VariantType_Double::instance) { value.doubleValue = v; }
var::var (MethodFunction m) noexcept : type (&VariantType_Method::instance) { value.methodValue = m; }
var::var (const Array<var>& v) : type (&VariantType_Array::instance) { value.arrayValue = new Array<var> (v); }
var::var (const String& v) : type (&VariantType_String::instance) { new (value.stringValue) String (v); }
var::var (const char* const v) : type (&VariantType_String::instance) { new (value.stringValue) String (v); }
var::var (const wchar_t* const v) : type (&VariantType_String::instance) { new (value.stringValue) String (v); }
var::var (const void* v, size_t sz) : type (&VariantType_Binary::instance) { value.binaryValue = new MemoryBlock (v, sz); }
var::var (const MemoryBlock& v) : type (&VariantType_Binary::instance) { value.binaryValue = new MemoryBlock (v); }
var::var (SharedObject* const object) : type (&VariantType_Object::instance)
{
value.objectValue = object;
if (object != nullptr)
object->incReferenceCount();
}
//==============================================================================
bool var::isVoid() const noexcept { return type->isVoid(); }
bool var::isInt() const noexcept { return type->isInt(); }
bool var::isInt64() const noexcept { return type->isInt64(); }
bool var::isBool() const noexcept { return type->isBool(); }
bool var::isDouble() const noexcept { return type->isDouble(); }
bool var::isString() const noexcept { return type->isString(); }
bool var::isObject() const noexcept { return type->isObject(); }
bool var::isArray() const noexcept { return type->isArray(); }
bool var::isBinaryData() const noexcept { return type->isBinary(); }
bool var::isMethod() const noexcept { return type->isMethod(); }
var::operator int() const noexcept { return type->toInt (value); }
var::operator int64() const noexcept { return type->toInt64 (value); }
var::operator bool() const noexcept { return type->toBool (value); }
var::operator float() const noexcept { return (float) type->toDouble (value); }
var::operator double() const noexcept { return type->toDouble (value); }
String var::toString() const { return type->toString (value); }
var::operator String() const { return type->toString (value); }
SharedObject* var::getObject() const noexcept { return type->toObject (value); }
Array<var>* var::getArray() const noexcept { return type->toArray (value); }
MemoryBlock* var::getBinaryData() const noexcept { return type->toBinary (value); }
DynamicObject* var::getDynamicObject() const noexcept { return dynamic_cast <DynamicObject*> (getObject()); }
//==============================================================================
void var::swapWith (var& other) noexcept
{
std::swap (type, other.type);
std::swap (value, other.value);
}
var& var::operator= (const var& v) { type->cleanUp (value); type = v.type; type->createCopy (value, v.value); return *this; }
var& var::operator= (const int v) { type->cleanUp (value); type = &VariantType_Int::instance; value.intValue = v; return *this; }
var& var::operator= (const int64 v) { type->cleanUp (value); type = &VariantType_Int64::instance; value.int64Value = v; return *this; }
var& var::operator= (const bool v) { type->cleanUp (value); type = &VariantType_Bool::instance; value.boolValue = v; return *this; }
var& var::operator= (const double v) { type->cleanUp (value); type = &VariantType_Double::instance; value.doubleValue = v; return *this; }
var& var::operator= (const char* const v) { type->cleanUp (value); type = &VariantType_String::instance; new (value.stringValue) String (v); return *this; }
var& var::operator= (const wchar_t* const v) { type->cleanUp (value); type = &VariantType_String::instance; new (value.stringValue) String (v); return *this; }
var& var::operator= (const String& v) { type->cleanUp (value); type = &VariantType_String::instance; new (value.stringValue) String (v); return *this; }
var& var::operator= (const Array<var>& v) { var v2 (v); swapWith (v2); return *this; }
var& var::operator= (SharedObject* v) { var v2 (v); swapWith (v2); return *this; }
var& var::operator= (MethodFunction v) { var v2 (v); swapWith (v2); return *this; }
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
var::var (var&& other) noexcept
: type (other.type),
value (other.value)
{
other.type = &VariantType_Void::instance;
}
var& var::operator= (var&& other) noexcept
{
swapWith (other);
return *this;
}
var::var (String&& v) : type (&VariantType_String::instance)
{
new (value.stringValue) String (static_cast<String&&> (v));
}
var::var (MemoryBlock&& v) : type (&VariantType_Binary::instance)
{
value.binaryValue = new MemoryBlock (static_cast<MemoryBlock&&> (v));
}
var& var::operator= (String&& v)
{
type->cleanUp (value);
type = &VariantType_String::instance;
new (value.stringValue) String (static_cast<String&&> (v));
return *this;
}
#endif
//==============================================================================
bool var::equals (const var& other) const noexcept
{
return type->equals (value, other.value, *other.type);
}
bool var::equalsWithSameType (const var& other) const noexcept
{
return type == other.type && equals (other);
}
bool operator== (const var& v1, const var& v2) noexcept { return v1.equals (v2); }
bool operator!= (const var& v1, const var& v2) noexcept { return ! v1.equals (v2); }
bool operator== (const var& v1, const String& v2) { return v1.toString() == v2; }
bool operator!= (const var& v1, const String& v2) { return v1.toString() != v2; }
bool operator== (const var& v1, const char* const v2) { return v1.toString() == v2; }
bool operator!= (const var& v1, const char* const v2) { return v1.toString() != v2; }
//==============================================================================
var var::operator[] (const Identifier propertyName) const
{
if (DynamicObject* const o = getDynamicObject())
return o->getProperty (propertyName);
return var::null;
}
var var::operator[] (const char* const propertyName) const
{
return operator[] (Identifier (propertyName));
}
var var::getProperty (const Identifier propertyName, const var& defaultReturnValue) const
{
if (DynamicObject* const o = getDynamicObject())
return o->getProperties().getWithDefault (propertyName, defaultReturnValue);
return defaultReturnValue;
}
var var::invoke (const Identifier method, const var* arguments, int numArguments) const
{
if (DynamicObject* const o = getDynamicObject())
return o->invokeMethod (method, arguments, numArguments);
return var::null;
}
var var::invokeMethod (DynamicObject* const target, const var* const arguments, const int numArguments) const
{
bassert (target != nullptr);
if (isMethod())
return (target->*(value.methodValue)) (arguments, numArguments);
return var::null;
}
var var::call (const Identifier method) const
{
return invoke (method, nullptr, 0);
}
var var::call (const Identifier method, const var& arg1) const
{
return invoke (method, &arg1, 1);
}
var var::call (const Identifier method, const var& arg1, const var& arg2) const
{
var args[] = { arg1, arg2 };
return invoke (method, args, 2);
}
var var::call (const Identifier method, const var& arg1, const var& arg2, const var& arg3)
{
var args[] = { arg1, arg2, arg3 };
return invoke (method, args, 3);
}
var var::call (const Identifier method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const
{
var args[] = { arg1, arg2, arg3, arg4 };
return invoke (method, args, 4);
}
var var::call (const Identifier method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const
{
var args[] = { arg1, arg2, arg3, arg4, arg5 };
return invoke (method, args, 5);
}
//==============================================================================
int var::size() const
{
if (const Array<var>* const array = getArray())
return array->size();
return 0;
}
const var& var::operator[] (int arrayIndex) const
{
const Array<var>* const array = getArray();
// When using this method, the var must actually be an array, and the index
// must be in-range!
bassert (array != nullptr && isPositiveAndBelow (arrayIndex, array->size()));
return array->getReference (arrayIndex);
}
var& var::operator[] (int arrayIndex)
{
const Array<var>* const array = getArray();
// When using this method, the var must actually be an array, and the index
// must be in-range!
bassert (array != nullptr && isPositiveAndBelow (arrayIndex, array->size()));
return array->getReference (arrayIndex);
}
Array<var>* var::convertToArray()
{
Array<var>* array = getArray();
if (array == nullptr)
{
const Array<var> tempVar;
var v (tempVar);
array = v.value.arrayValue;
if (! isVoid())
array->add (*this);
swapWith (v);
}
return array;
}
void var::append (const var& n)
{
convertToArray()->add (n);
}
void var::remove (const int index)
{
if (Array<var>* const array = getArray())
array->remove (index);
}
void var::insert (const int index, const var& n)
{
convertToArray()->insert (index, n);
}
void var::resize (const int numArrayElementsWanted)
{
convertToArray()->resize (numArrayElementsWanted);
}
int var::indexOf (const var& n) const
{
if (const Array<var>* const array = getArray())
return array->indexOf (n);
return -1;
}
//==============================================================================
void var::writeToStream (OutputStream& output) const
{
type->writeToStream (value, output);
}
var var::readFromStream (InputStream& input)
{
const int numBytes = input.readCompressedInt();
if (numBytes > 0)
{
switch (input.readByte())
{
case varMarker_Int: return var (input.readInt());
case varMarker_Int64: return var (input.readInt64());
case varMarker_BoolTrue: return var (true);
case varMarker_BoolFalse: return var (false);
case varMarker_Double: return var (input.readDouble());
case varMarker_String:
{
MemoryOutputStream mo;
mo.writeFromInputStream (input, numBytes - 1);
return var (mo.toUTF8());
}
case varMarker_Binary:
{
MemoryBlock mb ((size_t) numBytes - 1);
if (numBytes > 1)
{
const int numRead = input.read (mb.getData(), numBytes - 1);
mb.setSize ((size_t) numRead);
}
return var (mb);
}
case varMarker_Array:
{
var v;
Array<var>* const destArray = v.convertToArray();
for (int i = input.readCompressedInt(); --i >= 0;)
destArray->add (readFromStream (input));
return v;
}
default:
input.skipNextBytes (numBytes - 1); break;
}
}
return var::null;
}
} // namespace beast

View File

@@ -1,301 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_VARIANT_H_INCLUDED
#define BEAST_VARIANT_H_INCLUDED
namespace beast
{
#ifndef DOXYGEN
class SharedObject;
class DynamicObject;
#endif
//==============================================================================
/**
A variant class, that can be used to hold a range of primitive values.
A var object can hold a range of simple primitive values, strings, or
any kind of SharedObject. The var class is intended to act like
the kind of values used in dynamic scripting languages.
You can save/load var objects either in a small, proprietary binary format
using writeToStream()/readFromStream(), or as JSON by using the JSON class.
@see JSON, DynamicObject
*/
class BEAST_API var
{
public:
//==============================================================================
typedef const var (DynamicObject::*MethodFunction) (const var* arguments, int numArguments);
typedef Identifier identifier;
//==============================================================================
/** Creates a void variant. */
var() noexcept;
/** Destructor. */
~var() noexcept;
/** A static var object that can be used where you need an empty variant object. */
static const var null;
var (const var& valueToCopy);
var (int value) noexcept;
var (int64 value) noexcept;
var (bool value) noexcept;
var (double value) noexcept;
var (const char* value);
var (const wchar_t* value);
var (const String& value);
var (const Array<var>& value);
var (SharedObject* object);
var (MethodFunction method) noexcept;
var (const void* binaryData, size_t dataSize);
var (const MemoryBlock& binaryData);
var& operator= (const var& valueToCopy);
var& operator= (int value);
var& operator= (int64 value);
var& operator= (bool value);
var& operator= (double value);
var& operator= (const char* value);
var& operator= (const wchar_t* value);
var& operator= (const String& value);
var& operator= (const Array<var>& value);
var& operator= (SharedObject* object);
var& operator= (MethodFunction method);
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
var (var&& other) noexcept;
var (String&& value);
var (MemoryBlock&& binaryData);
var& operator= (var&& other) noexcept;
var& operator= (String&& value);
#endif
void swapWith (var& other) noexcept;
//==============================================================================
operator int() const noexcept;
operator int64() const noexcept;
operator bool() const noexcept;
operator float() const noexcept;
operator double() const noexcept;
operator String() const;
String toString() const;
/** If this variant holds an array, this provides access to it.
NOTE: Beware when you use this - the array pointer is only valid for the lifetime
of the variant that returned it, so be very careful not to call this method on temporary
var objects that are the return-value of a function, and which may go out of scope before
you use the array!
*/
Array<var>* getArray() const noexcept;
/** If this variant holds a memory block, this provides access to it.
NOTE: Beware when you use this - the MemoryBlock pointer is only valid for the lifetime
of the variant that returned it, so be very careful not to call this method on temporary
var objects that are the return-value of a function, and which may go out of scope before
you use the MemoryBlock!
*/
MemoryBlock* getBinaryData() const noexcept;
SharedObject* getObject() const noexcept;
DynamicObject* getDynamicObject() const noexcept;
//==============================================================================
bool isVoid() const noexcept;
bool isInt() const noexcept;
bool isInt64() const noexcept;
bool isBool() const noexcept;
bool isDouble() const noexcept;
bool isString() const noexcept;
bool isObject() const noexcept;
bool isArray() const noexcept;
bool isBinaryData() const noexcept;
bool isMethod() const noexcept;
/** Returns true if this var has the same value as the one supplied.
Note that this ignores the type, so a string var "123" and an integer var with the
value 123 are considered to be equal.
@see equalsWithSameType
*/
bool equals (const var& other) const noexcept;
/** Returns true if this var has the same value and type as the one supplied.
This differs from equals() because e.g. "123" and 123 will be considered different.
@see equals
*/
bool equalsWithSameType (const var& other) const noexcept;
//==============================================================================
/** If the var is an array, this returns the number of elements.
If the var isn't actually an array, this will return 0.
*/
int size() const;
/** If the var is an array, this can be used to return one of its elements.
To call this method, you must make sure that the var is actually an array, and
that the index is a valid number. If these conditions aren't met, behaviour is
undefined.
For more control over the array's contents, you can call getArray() and manipulate
it directly as an Array\<var\>.
*/
const var& operator[] (int arrayIndex) const;
/** If the var is an array, this can be used to return one of its elements.
To call this method, you must make sure that the var is actually an array, and
that the index is a valid number. If these conditions aren't met, behaviour is
undefined.
For more control over the array's contents, you can call getArray() and manipulate
it directly as an Array\<var\>.
*/
var& operator[] (int arrayIndex);
/** Appends an element to the var, converting it to an array if it isn't already one.
If the var isn't an array, it will be converted to one, and if its value was non-void,
this value will be kept as the first element of the new array. The parameter value
will then be appended to it.
For more control over the array's contents, you can call getArray() and manipulate
it directly as an Array\<var\>.
*/
void append (const var& valueToAppend);
/** Inserts an element to the var, converting it to an array if it isn't already one.
If the var isn't an array, it will be converted to one, and if its value was non-void,
this value will be kept as the first element of the new array. The parameter value
will then be inserted into it.
For more control over the array's contents, you can call getArray() and manipulate
it directly as an Array\<var\>.
*/
void insert (int index, const var& value);
/** If the var is an array, this removes one of its elements.
If the index is out-of-range or the var isn't an array, nothing will be done.
For more control over the array's contents, you can call getArray() and manipulate
it directly as an Array\<var\>.
*/
void remove (int index);
/** Treating the var as an array, this resizes it to contain the specified number of elements.
If the var isn't an array, it will be converted to one, and if its value was non-void,
this value will be kept as the first element of the new array before resizing.
For more control over the array's contents, you can call getArray() and manipulate
it directly as an Array\<var\>.
*/
void resize (int numArrayElementsWanted);
/** If the var is an array, this searches it for the first occurrence of the specified value,
and returns its index.
If the var isn't an array, or if the value isn't found, this returns -1.
*/
int indexOf (const var& value) const;
//==============================================================================
/** If this variant is an object, this returns one of its properties. */
var operator[] (const Identifier propertyName) const;
/** If this variant is an object, this returns one of its properties. */
var operator[] (const char* propertyName) const;
/** If this variant is an object, this returns one of its properties, or a default
fallback value if the property is not set. */
var getProperty (const Identifier propertyName, const var& defaultReturnValue) const;
/** If this variant is an object, this invokes one of its methods with no arguments. */
var call (const Identifier method) const;
/** If this variant is an object, this invokes one of its methods with one argument. */
var call (const Identifier method, const var& arg1) const;
/** If this variant is an object, this invokes one of its methods with 2 arguments. */
var call (const Identifier method, const var& arg1, const var& arg2) const;
/** If this variant is an object, this invokes one of its methods with 3 arguments. */
var call (const Identifier method, const var& arg1, const var& arg2, const var& arg3);
/** If this variant is an object, this invokes one of its methods with 4 arguments. */
var call (const Identifier method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const;
/** If this variant is an object, this invokes one of its methods with 5 arguments. */
var call (const Identifier method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const;
/** If this variant is an object, this invokes one of its methods with a list of arguments. */
var invoke (const Identifier method, const var* arguments, int numArguments) const;
//==============================================================================
/** Writes a binary representation of this value to a stream.
The data can be read back later using readFromStream().
@see JSON
*/
void writeToStream (OutputStream& output) const;
/** Reads back a stored binary representation of a value.
The data in the stream must have been written using writeToStream(), or this
will have unpredictable results.
@see JSON
*/
static var readFromStream (InputStream& input);
private:
//==============================================================================
class VariantType; friend class VariantType;
class VariantType_Void; friend class VariantType_Void;
class VariantType_Int; friend class VariantType_Int;
class VariantType_Int64; friend class VariantType_Int64;
class VariantType_Double; friend class VariantType_Double;
class VariantType_Bool; friend class VariantType_Bool;
class VariantType_String; friend class VariantType_String;
class VariantType_Object; friend class VariantType_Object;
class VariantType_Array; friend class VariantType_Array;
class VariantType_Binary; friend class VariantType_Binary;
class VariantType_Method; friend class VariantType_Method;
union ValueUnion
{
int intValue;
int64 int64Value;
bool boolValue;
double doubleValue;
char stringValue [sizeof (String)];
SharedObject* objectValue;
Array<var>* arrayValue;
MemoryBlock* binaryValue;
MethodFunction methodValue;
};
const VariantType* type;
ValueUnion value;
Array<var>* convertToArray();
friend class DynamicObject;
var invokeMethod (DynamicObject*, const var*, int) const;
};
/** Compares the values of two var objects, using the var::equals() comparison. */
bool operator== (const var& v1, const var& v2) noexcept;
/** Compares the values of two var objects, using the var::equals() comparison. */
bool operator!= (const var& v1, const var& v2) noexcept;
bool operator== (const var& v1, const String& v2);
bool operator!= (const var& v1, const String& v2);
bool operator== (const var& v1, const char* v2);
bool operator!= (const var& v1, const char* v2);
} // namespace beast
#endif // BEAST_VARIANT_H_INCLUDED

View File

@@ -1,45 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace beast
{
void FPUFlags::clearUnsetFlagsFrom (FPUFlags const& flags)
{
if (!flags.getMaskNaNs ().is_set ()) m_maskNaNs.clear ();
if (!flags.getMaskDenormals ().is_set ()) m_maskDenormals.clear ();
if (!flags.getMaskZeroDivides ().is_set ()) m_maskZeroDivides.clear ();
if (!flags.getMaskOverflows ().is_set ()) m_maskOverflows.clear ();
if (!flags.getMaskUnderflows ().is_set ()) m_maskUnderflows.clear ();
//if (!flags.getMaskInexacts().is_set ()) m_maskInexacts.clear ();
if (!flags.getFlushDenormals ().is_set ()) m_flushDenormals.clear ();
if (!flags.getInfinitySigned ().is_set ()) m_infinitySigned.clear ();
if (!flags.getRounding ().is_set ()) m_rounding.clear ();
if (!flags.getPrecision ().is_set ()) m_precision.clear ();
}
} // namespace beast

View File

@@ -1,340 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_FPUFLAGS_H_INCLUDED
#define BEAST_FPUFLAGS_H_INCLUDED
namespace beast
{
/*============================================================================*/
/**
A set of IEEE FPU flags.
Description.
@ingroup beast_core
*/
class BEAST_API FPUFlags
{
public:
/** An individual FPU flag */
struct Flag
{
Flag () : m_set (false) { }
Flag (Flag const& flag) : m_set (flag.m_set), m_value (flag.m_value) { }
Flag& operator= (Flag const& flag)
{
m_set = flag.m_set;
m_value = flag.m_value;
return *this;
}
bool is_set () const
{
return m_set;
}
bool value () const
{
assert (m_set);
return m_value;
}
void set_value (bool value)
{
m_set = true;
m_value = value;
}
void clear ()
{
m_set = false;
}
private:
bool m_set : 1;
bool m_value : 1;
};
/** A multi-valued FPU setting */
template <typename Constants>
struct Enum
{
Enum () : m_set (false) { }
Enum (Enum const& value) : m_set (value.m_set), m_value (value.m_value) { }
Enum& operator= (Enum const& value)
{
m_set = value.m_set;
m_value = value.m_value;
return *this;
}
bool is_set () const
{
return m_set;
}
Constants value () const
{
return m_value;
}
void set_value (Constants value)
{
m_set = true;
m_value = value;
}
void clear ()
{
m_set = false;
}
private:
bool m_set : 1;
Constants m_value;
};
public:
//
// Exception masks
//
void setMaskNaNs (bool mask = true)
{
m_maskNaNs.set_value (mask);
}
void setMaskDenormals (bool mask = true)
{
m_maskDenormals.set_value (mask);
}
void setMaskZeroDivides (bool mask = true)
{
m_maskZeroDivides.set_value (mask);
}
void setMaskOverflows (bool mask = true)
{
m_maskOverflows.set_value (mask);
}
void setMaskUnderflows (bool mask = true)
{
m_maskUnderflows.set_value (mask);
}
//void setMaskInexacts (bool mask = true) { m_maskInexacts.set_value (mask); }
void setUnmaskAllExceptions (bool unmask = true)
{
setMaskNaNs (!unmask);
setMaskDenormals (!unmask);
setMaskZeroDivides (!unmask);
setMaskOverflows (!unmask);
setMaskUnderflows (!unmask);
//setMaskInexacts (!unmask);
}
//
// Denormal control
//
void setFlushDenormals (bool flush = true)
{
m_flushDenormals.set_value (flush);
}
//
// Infinity control
//
void setInfinitySigned (bool is_signed = true)
{
m_infinitySigned.set_value (is_signed);
}
//
// Rounding control
//
enum Rounding
{
roundChop,
roundUp,
roundDown,
roundNear
};
void setRounding (Rounding rounding)
{
m_rounding.set_value (rounding);
}
//
// Precision control
//
enum Precision
{
bits24,
bits53,
bits64
};
void setPrecision (Precision precision)
{
m_precision.set_value (precision);
}
//
// Retrieval
//
const Flag getMaskNaNs () const
{
return m_maskNaNs;
}
const Flag getMaskDenormals () const
{
return m_maskDenormals;
}
const Flag getMaskZeroDivides () const
{
return m_maskZeroDivides;
}
const Flag getMaskOverflows () const
{
return m_maskOverflows;
}
const Flag getMaskUnderflows () const
{
return m_maskUnderflows;
}
//const Flag getMaskInexacts () const { return m_maskInexacts; }
const Flag getFlushDenormals () const
{
return m_flushDenormals;
}
const Flag getInfinitySigned () const
{
return m_infinitySigned;
}
const Enum <Rounding> getRounding () const
{
return m_rounding;
}
const Enum <Precision> getPrecision () const
{
return m_precision;
}
Flag& getMaskNaNs ()
{
return m_maskNaNs;
}
Flag& getMaskDenormals ()
{
return m_maskDenormals;
}
Flag& getMaskZeroDivides ()
{
return m_maskZeroDivides;
}
Flag& getMaskOverflows ()
{
return m_maskOverflows;
}
Flag& getMaskUnderflows ()
{
return m_maskUnderflows;
}
//Flag& getMaskInexacts () { return m_maskInexacts; }
Flag& getFlushDenormals ()
{
return m_flushDenormals;
}
Flag& getInfinitySigned ()
{
return m_infinitySigned;
}
Enum <Rounding>& getRounding ()
{
return m_rounding;
}
Enum <Precision>& getPrecision ()
{
return m_precision;
}
// Clears our flags if they are not set in another object
void clearUnsetFlagsFrom (FPUFlags const& flags);
// Retrieve the current flags fron the FPU
static FPUFlags getCurrent ();
// Change the current FPU flags based on what is set in flags
static void setCurrent (FPUFlags const& flags);
private:
Flag m_maskNaNs;
Flag m_maskDenormals;
Flag m_maskZeroDivides;
Flag m_maskOverflows;
Flag m_maskUnderflows;
//Flag m_maskInexacts;
Flag m_flushDenormals;
Flag m_infinitySigned;
Enum <Rounding> m_rounding;
Enum <Precision> m_precision;
};
//------------------------------------------------------------------------------
/*============================================================================*/
/**
IEEE FPU flag modifications with scoped lifetime.
An instance of the class saves the FPU flags and updates
FPUFlags flags;
flags.setUnmaskAllExceptions ();
{
ScopedFPUFlags fpu (flags);
// Perform floating point calculations
}
// FPU flags are back to what they were now
@ingroup beast_core
*/
class ScopedFPUFlags
{
public:
ScopedFPUFlags (FPUFlags const& flagsToSet)
{
m_savedFlags = FPUFlags::getCurrent ();
m_savedFlags.clearUnsetFlagsFrom (flagsToSet);
FPUFlags::setCurrent (flagsToSet);
}
~ScopedFPUFlags ()
{
FPUFlags::setCurrent (m_savedFlags);
}
private:
FPUFlags m_savedFlags;
};
} // namespace beast
#endif

View File

@@ -902,19 +902,6 @@ File File::createTempFile (const String& fileNameEnding)
return tempFile;
}
//==============================================================================
MemoryMappedFile::MemoryMappedFile (const File& file, MemoryMappedFile::AccessMode mode)
: address (nullptr), range (0, file.getSize()), fileHandle (0)
{
openInternal (file, mode);
}
MemoryMappedFile::MemoryMappedFile (const File& file, const Range<int64>& fileRange, AccessMode mode)
: address (nullptr), range (fileRange.getIntersectionWith (Range<int64> (0, file.getSize()))), fileHandle (0)
{
openInternal (file, mode);
}
//==============================================================================
class FileTests : public UnitTest
@@ -1049,37 +1036,6 @@ public:
expect (tempFile.getSize() == 10);
}
beginTestCase ("Memory-mapped files");
{
MemoryMappedFile mmf (tempFile, MemoryMappedFile::readOnly);
expect (mmf.getSize() == 10);
expect (mmf.getData() != nullptr);
expect (memcmp (mmf.getData(), "0123456789", 10) == 0);
}
{
const File tempFile2 (tempFile.getNonexistentSibling (false));
expect (tempFile2.create());
expect (tempFile2.appendData ("xxxxxxxxxx", 10));
{
MemoryMappedFile mmf (tempFile2, MemoryMappedFile::readWrite);
expect (mmf.getSize() == 10);
expect (mmf.getData() != nullptr);
memcpy (mmf.getData(), "abcdefghij", 10);
}
{
MemoryMappedFile mmf (tempFile2, MemoryMappedFile::readWrite);
expect (mmf.getSize() == 10);
expect (mmf.getData() != nullptr);
expect (memcmp (mmf.getData(), "abcdefghij", 10) == 0);
}
expect (tempFile2.deleteFile());
}
beginTestCase ("More writing");
expect (tempFile.appendData ("abcdefghij", 10));

View File

@@ -1,111 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_MEMORYMAPPEDFILE_H_INCLUDED
#define BEAST_MEMORYMAPPEDFILE_H_INCLUDED
namespace beast
{
//==============================================================================
/**
Maps a file into virtual memory for easy reading and/or writing.
*/
class BEAST_API MemoryMappedFile : LeakChecked <MemoryMappedFile>, public Uncopyable
{
public:
/** The read/write flags used when opening a memory mapped file. */
enum AccessMode
{
readOnly, /**< Indicates that the memory can only be read. */
readWrite /**< Indicates that the memory can be read and written to - changes that are
made will be flushed back to disk at the whim of the OS. */
};
/** Opens a file and maps it to an area of virtual memory.
The file should already exist, and should already be the size that you want to work with
when you call this. If the file is resized after being opened, the behaviour is undefined.
If the file exists and the operation succeeds, the getData() and getSize() methods will
return the location and size of the data that can be read or written. Note that the entire
file is not read into memory immediately - the OS simply creates a virtual mapping, which
will lazily pull the data into memory when blocks are accessed.
If the file can't be opened for some reason, the getData() method will return a null pointer.
*/
MemoryMappedFile (const File& file, AccessMode mode);
/** Opens a section of a file and maps it to an area of virtual memory.
The file should already exist, and should already be the size that you want to work with
when you call this. If the file is resized after being opened, the behaviour is undefined.
If the file exists and the operation succeeds, the getData() and getSize() methods will
return the location and size of the data that can be read or written. Note that the entire
file is not read into memory immediately - the OS simply creates a virtual mapping, which
will lazily pull the data into memory when blocks are accessed.
If the file can't be opened for some reason, the getData() method will return a null pointer.
NOTE: the start of the actual range used may be rounded-down to a multiple of the OS's page-size,
so do not assume that the mapped memory will begin at exactly the position you requested - always
use getRange() to check the actual range that is being used.
*/
MemoryMappedFile (const File& file,
const Range<int64>& fileRange,
AccessMode mode);
/** Destructor. */
~MemoryMappedFile();
/** Returns the address at which this file has been mapped, or a null pointer if
the file couldn't be successfully mapped.
*/
void* getData() const noexcept { return address; }
/** Returns the number of bytes of data that are available for reading or writing.
This will normally be the size of the file.
*/
size_t getSize() const noexcept { return (size_t) range.getLength(); }
/** Returns the section of the file at which the mapped memory represents. */
Range<int64> getRange() const noexcept { return range; }
private:
//==============================================================================
void* address;
Range<int64> range;
#if BEAST_WINDOWS
void* fileHandle;
#else
int fileHandle;
#endif
void openInternal (const File&, AccessMode);
};
} // namespace beast
#endif // BEAST_MEMORYMAPPEDFILE_H_INCLUDED

View File

@@ -1,647 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace beast
{
class JSONParser
{
public:
static Result parseObjectOrArray (String::CharPointerType t, var& result)
{
t = t.findEndOfWhitespace();
switch (t.getAndAdvance())
{
case 0: result = var::null; return Result::ok();
case '{': return parseObject (t, result);
case '[': return parseArray (t, result);
}
return createFail ("Expected '{' or '['", &t);
}
private:
static Result parseAny (String::CharPointerType& t, var& result)
{
t = t.findEndOfWhitespace();
String::CharPointerType t2 (t);
switch (t2.getAndAdvance())
{
case '{': t = t2; return parseObject (t, result);
case '[': t = t2; return parseArray (t, result);
case '"': t = t2; return parseString (t, result);
case '-':
t2 = t2.findEndOfWhitespace();
if (! CharacterFunctions::isDigit (*t2))
break;
t = t2;
return parseNumber (t, result, true);
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
return parseNumber (t, result, false);
case 't': // "true"
if (t2.getAndAdvance() == 'r' && t2.getAndAdvance() == 'u' && t2.getAndAdvance() == 'e')
{
t = t2;
result = var (true);
return Result::ok();
}
break;
case 'f': // "false"
if (t2.getAndAdvance() == 'a' && t2.getAndAdvance() == 'l'
&& t2.getAndAdvance() == 's' && t2.getAndAdvance() == 'e')
{
t = t2;
result = var (false);
return Result::ok();
}
break;
case 'n': // "null"
if (t2.getAndAdvance() == 'u' && t2.getAndAdvance() == 'l' && t2.getAndAdvance() == 'l')
{
t = t2;
result = var::null;
return Result::ok();
}
break;
default:
break;
}
return createFail ("Syntax error", &t);
}
static Result createFail (const char* const message, const String::CharPointerType* location = nullptr)
{
String m (message);
if (location != nullptr)
m << ": \"" << String (*location, 20) << '"';
return Result::fail (m);
}
static Result parseNumber (String::CharPointerType& t, var& result, const bool isNegative)
{
String::CharPointerType oldT (t);
int64 intValue = t.getAndAdvance() - '0';
bassert (intValue >= 0 && intValue < 10);
for (;;)
{
String::CharPointerType previousChar (t);
const beast_wchar c = t.getAndAdvance();
const int digit = ((int) c) - '0';
if (isPositiveAndBelow (digit, 10))
{
intValue = intValue * 10 + digit;
continue;
}
if (c == 'e' || c == 'E' || c == '.')
{
t = oldT;
const double asDouble = CharacterFunctions::readDoubleValue (t);
result = isNegative ? -asDouble : asDouble;
return Result::ok();
}
if (CharacterFunctions::isWhitespace (c)
|| c == ',' || c == '}' || c == ']' || c == 0)
{
t = previousChar;
break;
}
return createFail ("Syntax error in number", &oldT);
}
const int64 correctedValue = isNegative ? -intValue : intValue;
if ((intValue >> 31) != 0)
result = correctedValue;
else
result = (int) correctedValue;
return Result::ok();
}
static Result parseObject (String::CharPointerType& t, var& result)
{
DynamicObject* const resultObject = new DynamicObject();
result = resultObject;
NamedValueSet& resultProperties = resultObject->getProperties();
for (;;)
{
t = t.findEndOfWhitespace();
String::CharPointerType oldT (t);
const beast_wchar c = t.getAndAdvance();
if (c == '}')
break;
if (c == 0)
return createFail ("Unexpected end-of-input in object declaration");
if (c == '"')
{
var propertyNameVar;
Result r (parseString (t, propertyNameVar));
if (r.failed())
return r;
const String propertyName (propertyNameVar.toString());
if (propertyName.isNotEmpty())
{
t = t.findEndOfWhitespace();
oldT = t;
const beast_wchar c2 = t.getAndAdvance();
if (c2 != ':')
return createFail ("Expected ':', but found", &oldT);
resultProperties.set (propertyName, var::null);
var* propertyValue = resultProperties.getVarPointer (propertyName);
Result r2 (parseAny (t, *propertyValue));
if (r2.failed())
return r2;
t = t.findEndOfWhitespace();
oldT = t;
const beast_wchar nextChar = t.getAndAdvance();
if (nextChar == ',')
continue;
if (nextChar == '}')
break;
}
}
return createFail ("Expected object member declaration, but found", &oldT);
}
return Result::ok();
}
static Result parseArray (String::CharPointerType& t, var& result)
{
result = var (Array<var>());
Array<var>* const destArray = result.getArray();
for (;;)
{
t = t.findEndOfWhitespace();
String::CharPointerType oldT (t);
const beast_wchar c = t.getAndAdvance();
if (c == ']')
break;
if (c == 0)
return createFail ("Unexpected end-of-input in array declaration");
t = oldT;
destArray->add (var::null);
Result r (parseAny (t, destArray->getReference (destArray->size() - 1)));
if (r.failed())
return r;
t = t.findEndOfWhitespace();
oldT = t;
const beast_wchar nextChar = t.getAndAdvance();
if (nextChar == ',')
continue;
if (nextChar == ']')
break;
return createFail ("Expected object array item, but found", &oldT);
}
return Result::ok();
}
static Result parseString (String::CharPointerType& t, var& result)
{
MemoryOutputStream buffer (256);
for (;;)
{
beast_wchar c = t.getAndAdvance();
if (c == '"')
break;
if (c == '\\')
{
c = t.getAndAdvance();
switch (c)
{
case '"':
case '\\':
case '/': break;
case 'b': c = '\b'; break;
case 'f': c = '\f'; break;
case 'n': c = '\n'; break;
case 'r': c = '\r'; break;
case 't': c = '\t'; break;
case 'u':
{
c = 0;
for (int i = 4; --i >= 0;)
{
const int digitValue = CharacterFunctions::getHexDigitValue (t.getAndAdvance());
if (digitValue < 0)
return createFail ("Syntax error in unicode escape sequence");
c = (beast_wchar) ((c << 4) + digitValue);
}
break;
}
}
}
if (c == 0)
return createFail ("Unexpected end-of-input in string constant");
buffer.appendUTF8Char (c);
}
result = buffer.toUTF8 ();
return Result::ok();
}
};
//==============================================================================
class JSONFormatter
{
public:
static void write (OutputStream& out, const var& v,
const int indentLevel, const bool allOnOneLine)
{
if (v.isString())
{
writeString (out, v.toString().getCharPointer());
}
else if (v.isVoid())
{
out << "null";
}
else if (v.isBool())
{
out << (static_cast<bool> (v) ? "true" : "false");
}
else if (v.isArray())
{
writeArray (out, *v.getArray(), indentLevel, allOnOneLine);
}
else if (v.isObject())
{
if (DynamicObject* const object = v.getDynamicObject())
writeObject (out, *object, indentLevel, allOnOneLine);
else
bassertfalse; // Only DynamicObjects can be converted to JSON!
}
else
{
// Can't convert these other types of object to JSON!
bassert (! (v.isMethod() || v.isBinaryData()));
out << v.toString();
}
}
private:
enum { indentSize = 2 };
static void writeEscapedChar (OutputStream& out, const unsigned short value)
{
out << "\\u" << String::toHexString ((int) value).paddedLeft ('0', 4);
}
static void writeString (OutputStream& out, String::CharPointerType t)
{
out << '"';
for (;;)
{
const beast_wchar c (t.getAndAdvance());
switch (c)
{
case 0: out << '"'; return;
case '\"': out << "\\\""; break;
case '\\': out << "\\\\"; break;
case '\b': out << "\\b"; break;
case '\f': out << "\\f"; break;
case '\t': out << "\\t"; break;
case '\r': out << "\\r"; break;
case '\n': out << "\\n"; break;
default:
if (c >= 32 && c < 127)
{
out << (char) c;
}
else
{
if (CharPointer_UTF16::getBytesRequiredFor (c) > 2)
{
CharPointer_UTF16::CharType chars[2];
CharPointer_UTF16 utf16 (chars);
utf16.write (c);
for (int i = 0; i < 2; ++i)
writeEscapedChar (out, (unsigned short) chars[i]);
}
else
{
writeEscapedChar (out, (unsigned short) c);
}
}
break;
}
}
}
static void writeSpaces (OutputStream& out, int numSpaces)
{
out.writeRepeatedByte (' ', (size_t) numSpaces);
}
static void writeArray (OutputStream& out, const Array<var>& array,
const int indentLevel, const bool allOnOneLine)
{
out << '[';
if (! allOnOneLine)
out << newLine;
for (int i = 0; i < array.size(); ++i)
{
if (! allOnOneLine)
writeSpaces (out, indentLevel + indentSize);
write (out, array.getReference(i), indentLevel + indentSize, allOnOneLine);
if (i < array.size() - 1)
{
if (allOnOneLine)
out << ", ";
else
out << ',' << newLine;
}
else if (! allOnOneLine)
out << newLine;
}
if (! allOnOneLine)
writeSpaces (out, indentLevel);
out << ']';
}
static void writeObject (OutputStream& out, DynamicObject& object,
const int indentLevel, const bool allOnOneLine)
{
NamedValueSet& props = object.getProperties();
out << '{';
if (! allOnOneLine)
out << newLine;
LinkedListPointer<NamedValueSet::NamedValue>* i = &(props.values);
for (;;)
{
NamedValueSet::NamedValue* const v = i->get();
if (v == nullptr)
break;
if (! allOnOneLine)
writeSpaces (out, indentLevel + indentSize);
writeString (out, v->name);
out << ": ";
write (out, v->value, indentLevel + indentSize, allOnOneLine);
if (v->nextListItem.get() != nullptr)
{
if (allOnOneLine)
out << ", ";
else
out << ',' << newLine;
}
else if (! allOnOneLine)
out << newLine;
i = &(v->nextListItem);
}
if (! allOnOneLine)
writeSpaces (out, indentLevel);
out << '}';
}
};
//==============================================================================
var JSON::parse (const String& text)
{
var result;
if (! JSONParser::parseObjectOrArray (text.getCharPointer(), result))
result = var::null;
return result;
}
var JSON::parse (InputStream& input)
{
return parse (input.readEntireStreamAsString());
}
var JSON::parse (const File& file)
{
return parse (file.loadFileAsString());
}
Result JSON::parse (const String& text, var& result)
{
return JSONParser::parseObjectOrArray (text.getCharPointer(), result);
}
String JSON::toString (const var& data, const bool allOnOneLine)
{
MemoryOutputStream mo (1024);
JSONFormatter::write (mo, data, 0, allOnOneLine);
return mo.toUTF8 ();
}
void JSON::writeToStream (OutputStream& output, const var& data, const bool allOnOneLine)
{
JSONFormatter::write (output, data, 0, allOnOneLine);
}
//==============================================================================
//==============================================================================
class JSONTests : public UnitTest
{
public:
JSONTests() : UnitTest ("JSON", "beast") { }
static String createRandomWideCharString (Random& r)
{
beast_wchar buffer[40] = { 0 };
for (int i = 0; i < numElementsInArray (buffer) - 1; ++i)
{
if (r.nextBool())
{
do
{
buffer[i] = (beast_wchar) (1 + r.nextInt (0x10ffff - 1));
}
while (! CharPointer_UTF16::canRepresent (buffer[i]));
}
else
buffer[i] = (beast_wchar) (1 + r.nextInt (0xff));
}
return CharPointer_UTF32 (buffer);
}
static String createRandomIdentifier (Random& r)
{
char buffer[30] = { 0 };
for (int i = 0; i < numElementsInArray (buffer) - 1; ++i)
{
static const char chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-:";
buffer[i] = chars [r.nextInt (sizeof (chars) - 1)];
}
return CharPointer_ASCII (buffer);
}
static var createRandomVar (Random& r, int depth)
{
switch (r.nextInt (depth > 3 ? 6 : 8))
{
case 0: return var::null;
case 1: return r.nextInt();
case 2: return r.nextInt64();
case 3: return r.nextBool();
case 4: return r.nextDouble();
case 5: return createRandomWideCharString (r);
case 6:
{
var v (createRandomVar (r, depth + 1));
for (int i = 1 + r.nextInt (30); --i >= 0;)
v.append (createRandomVar (r, depth + 1));
return v;
}
case 7:
{
DynamicObject* o = new DynamicObject();
for (int i = r.nextInt (30); --i >= 0;)
o->setProperty (createRandomIdentifier (r), createRandomVar (r, depth + 1));
return o;
}
default:
return var::null;
}
}
void runTest()
{
beginTestCase ("JSON");
Random r;
r.setSeedRandomly();
expect (JSON::parse (String::empty) == var::null);
expect (JSON::parse ("{}").isObject());
expect (JSON::parse ("[]").isArray());
expect (JSON::parse ("[ 1234 ]")[0].isInt());
expect (JSON::parse ("[ 12345678901234 ]")[0].isInt64());
expect (JSON::parse ("[ 1.123e3 ]")[0].isDouble());
expect (JSON::parse ("[ -1234]")[0].isInt());
expect (JSON::parse ("[-12345678901234]")[0].isInt64());
expect (JSON::parse ("[-1.123e3]")[0].isDouble());
for (int i = 100; --i >= 0;)
{
var v;
if (i > 0)
v = createRandomVar (r, 0);
const bool oneLine = r.nextBool();
String asString (JSON::toString (v, oneLine));
var parsed = JSON::parse ("[" + asString + "]")[0];
String parsedString (JSON::toString (parsed, oneLine));
expect (asString.isNotEmpty() && parsedString == asString);
}
}
};
static JSONTests jsonTests;
} // namespace beast

View File

@@ -1,114 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_JSON_H_INCLUDED
#define BEAST_JSON_H_INCLUDED
namespace beast
{
class InputStream;
class OutputStream;
class File;
//==============================================================================
/**
Contains static methods for converting JSON-formatted text to and from var objects.
The var class is structurally compatible with JSON-formatted data, so these
functions allow you to parse JSON into a var object, and to convert a var
object to JSON-formatted text.
@see var
*/
class BEAST_API JSON
{
public:
//==============================================================================
/** Parses a string of JSON-formatted text, and returns a result code containing
any parse errors.
This will return the parsed structure in the parsedResult parameter, and will
return a Result object to indicate whether parsing was successful, and if not,
it will contain an error message.
If you're not interested in the error message, you can use one of the other
shortcut parse methods, which simply return a var::null if the parsing fails.
*/
static Result parse (const String& text, var& parsedResult);
/** Attempts to parse some JSON-formatted text, and returns the result as a var object.
If the parsing fails, this simply returns var::null - if you need to find out more
detail about the parse error, use the alternative parse() method which returns a Result.
*/
static var parse (const String& text);
/** Attempts to parse some JSON-formatted text from a file, and returns the result
as a var object.
Note that this is just a short-cut for reading the entire file into a string and
parsing the result.
If the parsing fails, this simply returns var::null - if you need to find out more
detail about the parse error, use the alternative parse() method which returns a Result.
*/
static var parse (const File& file);
/** Attempts to parse some JSON-formatted text from a stream, and returns the result
as a var object.
Note that this is just a short-cut for reading the entire stream into a string and
parsing the result.
If the parsing fails, this simply returns var::null - if you need to find out more
detail about the parse error, use the alternative parse() method which returns a Result.
*/
static var parse (InputStream& input);
//==============================================================================
/** Returns a string which contains a JSON-formatted representation of the var object.
If allOnOneLine is true, the result will be compacted into a single line of text
with no carriage-returns. If false, it will be laid-out in a more human-readable format.
@see writeToStream
*/
static String toString (const var& objectToFormat,
bool allOnOneLine = false);
/** Writes a JSON-formatted representation of the var object to the given stream.
If allOnOneLine is true, the result will be compacted into a single line of text
with no carriage-returns. If false, it will be laid-out in a more human-readable format.
@see toString
*/
static void writeToStream (OutputStream& output,
const var& objectToFormat,
bool allOnOneLine = false);
private:
//==============================================================================
JSON(); // This class can't be instantiated - just use its static methods.
};
} // namespace beast
#endif // BEAST_JSON_H_INCLUDED

View File

@@ -1,134 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace beast
{
FileLogger::FileLogger (const File& file,
const String& welcomeMessage,
const int64 maxInitialFileSizeBytes)
: logFile (file)
{
if (maxInitialFileSizeBytes >= 0)
trimFileSize (maxInitialFileSizeBytes);
if (! file.exists())
file.create(); // (to create the parent directories)
String welcome;
welcome << newLine
<< "**********************************************************" << newLine
<< welcomeMessage << newLine
<< "Log started: " << Time::getCurrentTime().toString (true, true) << newLine;
FileLogger::logMessage (welcome);
}
FileLogger::~FileLogger() {}
//==============================================================================
void FileLogger::logMessage (const String& message)
{
const ScopedLock sl (logLock);
BDBG (message);
FileOutputStream out (logFile, 256);
out << message << newLine;
}
void FileLogger::trimFileSize (int64 maxFileSizeBytes) const
{
if (maxFileSizeBytes <= 0)
{
logFile.deleteFile();
}
else
{
const int64 fileSize = logFile.getSize();
if (fileSize > maxFileSizeBytes)
{
TemporaryFile tempFile (logFile);
{
FileOutputStream out (tempFile.getFile());
FileInputStream in (logFile);
if (! (out.openedOk() && in.openedOk()))
return;
in.setPosition (fileSize - maxFileSizeBytes);
for (;;)
{
const char c = in.readByte();
if (c == 0)
return;
if (c == '\n' || c == '\r')
{
out << c;
break;
}
}
out.writeFromInputStream (in, -1);
}
tempFile.overwriteTargetFileWithTemporary();
}
}
}
//==============================================================================
File FileLogger::getSystemLogFileFolder()
{
#if BEAST_MAC
return File ("~/Library/Logs");
#else
return File::getSpecialLocation (File::userApplicationDataDirectory);
#endif
}
FileLogger* FileLogger::createDefaultAppLogger (const String& logFileSubDirectoryName,
const String& logFileName,
const String& welcomeMessage,
const int64 maxInitialFileSizeBytes)
{
return new FileLogger (getSystemLogFileFolder().getChildFile (logFileSubDirectoryName)
.getChildFile (logFileName),
welcomeMessage, maxInitialFileSizeBytes);
}
FileLogger* FileLogger::createDateStampedLogger (const String& logFileSubDirectoryName,
const String& logFileNameRoot,
const String& logFileNameSuffix,
const String& welcomeMessage)
{
return new FileLogger (getSystemLogFileFolder().getChildFile (logFileSubDirectoryName)
.getChildFile (logFileNameRoot + Time::getCurrentTime().formatted ("%Y-%m-%d_%H-%M-%S"))
.withFileExtension (logFileNameSuffix)
.getNonexistentSibling(),
welcomeMessage, 0);
}
} // namespace beast

View File

@@ -1,134 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_FILELOGGER_H_INCLUDED
#define BEAST_FILELOGGER_H_INCLUDED
namespace beast
{
//==============================================================================
/**
A simple implementation of a Logger that writes to a file.
@see Logger
*/
class BEAST_API FileLogger
: public Logger
, LeakChecked <FileLogger>
, public Uncopyable
{
public:
//==============================================================================
/** Creates a FileLogger for a given file.
@param fileToWriteTo the file that to use - new messages will be appended
to the file. If the file doesn't exist, it will be created,
along with any parent directories that are needed.
@param welcomeMessage when opened, the logger will write a header to the log, along
with the current date and time, and this welcome message
@param maxInitialFileSizeBytes if this is zero or greater, then if the file already exists
but is larger than this number of bytes, then the start of the
file will be truncated to keep the size down. This prevents a log
file getting ridiculously large over time. The file will be truncated
at a new-line boundary. If this value is less than zero, no size limit
will be imposed; if it's zero, the file will always be deleted. Note that
the size is only checked once when this object is created - any logging
that is done later will be appended without any checking
*/
FileLogger (const File& fileToWriteTo,
const String& welcomeMessage,
const int64 maxInitialFileSizeBytes = 128 * 1024);
/** Destructor. */
~FileLogger();
//==============================================================================
/** Returns the file that this logger is writing to. */
const File& getLogFile() const noexcept { return logFile; }
//==============================================================================
/** Helper function to create a log file in the correct place for this platform.
The method might return nullptr if the file can't be created for some reason.
@param logFileSubDirectoryName the name of the subdirectory to create inside the logs folder (as
returned by getSystemLogFileFolder). It's best to use something
like the name of your application here.
@param logFileName the name of the file to create, e.g. "MyAppLog.txt".
@param welcomeMessage a message that will be written to the log when it's opened.
@param maxInitialFileSizeBytes (see the FileLogger constructor for more info on this)
*/
static FileLogger* createDefaultAppLogger (const String& logFileSubDirectoryName,
const String& logFileName,
const String& welcomeMessage,
const int64 maxInitialFileSizeBytes = 128 * 1024);
/** Helper function to create a log file in the correct place for this platform.
The filename used is based on the root and suffix strings provided, along with a
time and date string, meaning that a new, empty log file will be always be created
rather than appending to an exising one.
The method might return nullptr if the file can't be created for some reason.
@param logFileSubDirectoryName the name of the subdirectory to create inside the logs folder (as
returned by getSystemLogFileFolder). It's best to use something
like the name of your application here.
@param logFileNameRoot the start of the filename to use, e.g. "MyAppLog_". This will have
a timestamp and the logFileNameSuffix appended to it
@param logFileNameSuffix the file suffix to use, e.g. ".txt"
@param welcomeMessage a message that will be written to the log when it's opened.
*/
static FileLogger* createDateStampedLogger (const String& logFileSubDirectoryName,
const String& logFileNameRoot,
const String& logFileNameSuffix,
const String& welcomeMessage);
//==============================================================================
/** Returns an OS-specific folder where log-files should be stored.
On Windows this will return a logger with a path such as:
c:\\Documents and Settings\\username\\Application Data\\[logFileSubDirectoryName]\\[logFileName]
On the Mac it'll create something like:
~/Library/Logs/[logFileSubDirectoryName]/[logFileName]
@see createDefaultAppLogger
*/
static File getSystemLogFileFolder();
// (implementation of the Logger virtual method)
void logMessage (const String&);
private:
//==============================================================================
File logFile;
CriticalSection logLock;
void trimFileSize (int64 maxFileSizeBytes) const;
};
} // namespace beast
#endif // BEAST_FILELOGGER_H_INCLUDED

View File

@@ -36,8 +36,6 @@ namespace beast
The logger class also contains methods for writing messages to the debugger's
output stream.
@see FileLogger
*/
class BEAST_API Logger
{

File diff suppressed because it is too large Load Diff

View File

@@ -1,326 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_BIGINTEGER_H_INCLUDED
#define BEAST_BIGINTEGER_H_INCLUDED
namespace beast
{
//==============================================================================
/**
An arbitrarily large integer class.
A BigInteger can be used in a similar way to a normal integer, but has no size
limit (except for memory and performance constraints).
Negative values are possible, but the value isn't stored as 2s-complement, so
be careful if you use negative values and look at the values of individual bits.
*/
class BEAST_API BigInteger : LeakChecked <BigInteger>
{
public:
//==============================================================================
/** Creates an empty BigInteger */
BigInteger();
/** Creates a BigInteger containing an integer value in its low bits.
The low 32 bits of the number are initialised with this value.
*/
BigInteger (uint32 value);
/** Creates a BigInteger containing an integer value in its low bits.
The low 32 bits of the number are initialised with the absolute value
passed in, and its sign is set to reflect the sign of the number.
*/
BigInteger (int32 value);
/** Creates a BigInteger containing an integer value in its low bits.
The low 64 bits of the number are initialised with the absolute value
passed in, and its sign is set to reflect the sign of the number.
*/
BigInteger (int64 value);
/** Creates a copy of another BigInteger. */
BigInteger (const BigInteger& other);
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
BigInteger (BigInteger&& other) noexcept;
BigInteger& operator= (BigInteger&& other) noexcept;
#endif
/** Destructor. */
~BigInteger();
//==============================================================================
/** Copies another BigInteger onto this one. */
BigInteger& operator= (const BigInteger& other);
/** Swaps the internal contents of this with another object. */
void swapWith (BigInteger& other) noexcept;
//==============================================================================
/** Returns the value of a specified bit in the number.
If the index is out-of-range, the result will be false.
*/
bool operator[] (int bit) const noexcept;
/** Returns true if no bits are set. */
bool isZero() const noexcept;
/** Returns true if the value is 1. */
bool isOne() const noexcept;
/** Attempts to get the lowest bits of the value as an integer.
If the value is bigger than the integer limits, this will return only the lower bits.
*/
int toInteger() const noexcept;
//==============================================================================
/** Resets the value to 0. */
void clear();
/** Clears a particular bit in the number. */
void clearBit (int bitNumber) noexcept;
/** Sets a specified bit to 1. */
void setBit (int bitNumber);
/** Sets or clears a specified bit. */
void setBit (int bitNumber, bool shouldBeSet);
/** Sets a range of bits to be either on or off.
@param startBit the first bit to change
@param numBits the number of bits to change
@param shouldBeSet whether to turn these bits on or off
*/
void setRange (int startBit, int numBits, bool shouldBeSet);
/** Inserts a bit an a given position, shifting up any bits above it. */
void insertBit (int bitNumber, bool shouldBeSet);
/** Returns a range of bits as a new BigInteger.
e.g. getBitRangeAsInt (0, 64) would return the lowest 64 bits.
@see getBitRangeAsInt
*/
BigInteger getBitRange (int startBit, int numBits) const;
/** Returns a range of bits as an integer value.
e.g. getBitRangeAsInt (0, 32) would return the lowest 32 bits.
Asking for more than 32 bits isn't allowed (obviously) - for that, use
getBitRange().
*/
uint32 getBitRangeAsInt (int startBit, int numBits) const noexcept;
/** Sets a range of bits to an integer value.
Copies the given integer onto a range of bits, starting at startBit,
and using up to numBits of the available bits.
*/
void setBitRangeAsInt (int startBit, int numBits, uint32 valueToSet);
/** Shifts a section of bits left or right.
@param howManyBitsLeft how far to move the bits (+ve numbers shift it left, -ve numbers shift it right).
@param startBit the first bit to affect - if this is > 0, only bits above that index will be affected.
*/
void shiftBits (int howManyBitsLeft, int startBit);
/** Returns the total number of set bits in the value. */
int countNumberOfSetBits() const noexcept;
/** Looks for the index of the next set bit after a given starting point.
This searches from startIndex (inclusive) upwards for the first set bit,
and returns its index. If no set bits are found, it returns -1.
*/
int findNextSetBit (int startIndex) const noexcept;
/** Looks for the index of the next clear bit after a given starting point.
This searches from startIndex (inclusive) upwards for the first clear bit,
and returns its index.
*/
int findNextClearBit (int startIndex) const noexcept;
/** Returns the index of the highest set bit in the number.
If the value is zero, this will return -1.
*/
int getHighestBit() const noexcept;
//==============================================================================
// All the standard arithmetic ops...
BigInteger& operator+= (const BigInteger& other);
BigInteger& operator-= (const BigInteger& other);
BigInteger& operator*= (const BigInteger& other);
BigInteger& operator/= (const BigInteger& other);
BigInteger& operator|= (const BigInteger& other);
BigInteger& operator&= (const BigInteger& other);
BigInteger& operator^= (const BigInteger& other);
BigInteger& operator%= (const BigInteger& other);
BigInteger& operator<<= (int numBitsToShift);
BigInteger& operator>>= (int numBitsToShift);
BigInteger& operator++();
BigInteger& operator--();
BigInteger operator++ (int);
BigInteger operator-- (int);
BigInteger operator-() const;
BigInteger operator+ (const BigInteger& other) const;
BigInteger operator- (const BigInteger& other) const;
BigInteger operator* (const BigInteger& other) const;
BigInteger operator/ (const BigInteger& other) const;
BigInteger operator| (const BigInteger& other) const;
BigInteger operator& (const BigInteger& other) const;
BigInteger operator^ (const BigInteger& other) const;
BigInteger operator% (const BigInteger& other) const;
BigInteger operator<< (int numBitsToShift) const;
BigInteger operator>> (int numBitsToShift) const;
bool operator== (const BigInteger& other) const noexcept;
bool operator!= (const BigInteger& other) const noexcept;
bool operator< (const BigInteger& other) const noexcept;
bool operator<= (const BigInteger& other) const noexcept;
bool operator> (const BigInteger& other) const noexcept;
bool operator>= (const BigInteger& other) const noexcept;
//==============================================================================
/** Does a signed comparison of two BigIntegers.
Return values are:
- 0 if the numbers are the same
- < 0 if this number is smaller than the other
- > 0 if this number is bigger than the other
*/
int compare (const BigInteger& other) const noexcept;
/** Compares the magnitudes of two BigIntegers, ignoring their signs.
Return values are:
- 0 if the numbers are the same
- < 0 if this number is smaller than the other
- > 0 if this number is bigger than the other
*/
int compareAbsolute (const BigInteger& other) const noexcept;
/** Divides this value by another one and returns the remainder.
This number is divided by other, leaving the quotient in this number,
with the remainder being copied to the other BigInteger passed in.
*/
void divideBy (const BigInteger& divisor, BigInteger& remainder);
/** Returns the largest value that will divide both this value and the one passed-in.
*/
BigInteger findGreatestCommonDivisor (BigInteger other) const;
/** Performs a combined exponent and modulo operation.
This BigInteger's value becomes (this ^ exponent) % modulus.
*/
void exponentModulo (const BigInteger& exponent, const BigInteger& modulus);
/** Performs an inverse modulo on the value.
i.e. the result is (this ^ -1) mod (modulus).
*/
void inverseModulo (const BigInteger& modulus);
//==============================================================================
/** Returns true if the value is less than zero.
@see setNegative, negate
*/
bool isNegative() const noexcept;
/** Changes the sign of the number to be positive or negative.
@see isNegative, negate
*/
void setNegative (bool shouldBeNegative) noexcept;
/** Inverts the sign of the number.
@see isNegative, setNegative
*/
void negate() noexcept;
//==============================================================================
/** Converts the number to a string.
Specify a base such as 2 (binary), 8 (octal), 10 (decimal), 16 (hex).
If minimumNumCharacters is greater than 0, the returned string will be
padded with leading zeros to reach at least that length.
*/
String toString (int base, int minimumNumCharacters = 1) const;
/** Reads the numeric value from a string.
Specify a base such as 2 (binary), 8 (octal), 10 (decimal), 16 (hex).
Any invalid characters will be ignored.
*/
void parseString (const String& text, int base);
//==============================================================================
/** Turns the number into a block of binary data.
The data is arranged as little-endian, so the first byte of data is the low 8 bits
of the number, and so on.
@see loadFromMemoryBlock
*/
MemoryBlock toMemoryBlock() const;
/** Converts a block of raw data into a number.
The data is arranged as little-endian, so the first byte of data is the low 8 bits
of the number, and so on.
@see toMemoryBlock
*/
void loadFromMemoryBlock (const MemoryBlock& data);
private:
//==============================================================================
HeapBlock <uint32> values;
size_t numValues;
int highestBit;
bool negative;
void ensureSize (size_t numVals);
void shiftLeft (int bits, int startBit);
void shiftRight (int bits, int startBit);
};
/** Writes a BigInteger to an OutputStream as a UTF8 decimal string. */
OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const BigInteger& value);
//==============================================================================
#ifndef DOXYGEN
// For backwards compatibility, BitArray is defined as an alias for BigInteger.
typedef BigInteger BitArray;
#endif
} // namespace beast
#endif // BEAST_BIGINTEGER_H_INCLUDED

View File

@@ -106,19 +106,6 @@ double Random::nextDouble() noexcept
return static_cast <uint32> (nextInt()) / (double) 0xffffffff;
}
BigInteger Random::nextLargeNumber (const BigInteger& maximumValue)
{
BigInteger n;
do
{
fillBitsRandomly (n, 0, maximumValue.getHighestBit() + 1);
}
while (n >= maximumValue);
return n;
}
void Random::fillBitsRandomly (void* const buffer, size_t bytes)
{
int* d = static_cast<int*> (buffer);
@@ -133,27 +120,6 @@ void Random::fillBitsRandomly (void* const buffer, size_t bytes)
}
}
void Random::fillBitsRandomly (BigInteger& arrayToChange, int startBit, int numBits)
{
arrayToChange.setBit (startBit + numBits - 1, true); // to force the array to pre-allocate space
while ((startBit & 31) != 0 && numBits > 0)
{
arrayToChange.setBit (startBit++, nextBool());
--numBits;
}
while (numBits >= 32)
{
arrayToChange.setBitRangeAsInt (startBit, 32, (unsigned int) nextInt());
startBit += 32;
numBits -= 32;
}
while (--numBits >= 0)
arrayToChange.setBit (startBit + numBits, nextBool());
}
//==============================================================================
class RandomTests : public UnitTest

View File

@@ -89,18 +89,9 @@ public:
*/
bool nextBool() noexcept;
/** Returns a BigInteger containing a random number.
@returns a random value in the range 0 to (maximumValue - 1).
*/
BigInteger nextLargeNumber (const BigInteger& maximumValue);
/** Fills a block of memory with random values. */
void fillBitsRandomly (void* bufferToFill, size_t sizeInBytes);
/** Sets a range of bits in a BigInteger to random values. */
void fillBitsRandomly (BigInteger& arrayToChange, int startBit, int numBits);
//==============================================================================
/** Resets this Random object to a given seed value. */
void setSeed (int64 newSeed) noexcept;

View File

@@ -1,422 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_CACHELINE_H_INCLUDED
#define BEAST_CACHELINE_H_INCLUDED
// Allows turning off of all padding,
// e.g. for memory-constrained systems or testing.
//
#define GLOBAL_PADDING_ENABLED 1
namespace beast
{
namespace CacheLine
{
#if GLOBAL_PADDING_ENABLED
/** Pad an object to start on a cache line boundary.
Up to 8 constructor parameters are passed through.
*/
template <typename T>
class Aligned
{
public:
Aligned ()
{
new (&get()) T;
}
template <class T1>
Aligned (T1 t1)
{
new (&get()) T (t1);
}
template <class T1, class T2>
Aligned (T1 t1, T2 t2)
{
new (&get()) T (t1, t2);
}
template <class T1, class T2, class T3>
Aligned (T1 t1, T2 t2, T3 t3)
{
new (&get()) T (t1, t2, t3);
}
template <class T1, class T2, class T3, class T4>
Aligned (T1 t1, T2 t2, T3 t3, T4 t4)
{
new (&get()) T (t1, t2, t3, t4);
}
template <class T1, class T2, class T3, class T4, class T5>
Aligned (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
{
new (&get()) T (t1, t2, t3, t4, t5);
}
template <class T1, class T2, class T3, class T4, class T5, class T6>
Aligned (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
{
new (&get()) T (t1, t2, t3, t4, t5, t6);
}
template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
Aligned (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7)
{
new (&get()) T (t1, t2, t3, t4, t5, t6, t7);
}
template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
Aligned (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
{
new (&get()) T (t1, t2, t3, t4, t5, t6, t7, t8);
}
~Aligned ()
{
get().~T ();
}
T& operator= (T const& other)
{
return (get() = other);
}
T& get () noexcept { return *ptr(); }
T& operator* () noexcept { return get(); }
T* operator-> () noexcept { return &get(); }
operator T& () noexcept { return get(); }
operator T* () noexcept { return &get(); }
T const& get () const noexcept { return *ptr(); }
const T& operator* () const noexcept { return get(); }
const T* operator-> () const noexcept { return &get(); }
operator T const& () const noexcept { return get(); }
operator T const* () const noexcept { return &get(); }
private:
T* ptr () const noexcept
{
return (T*) ((uintptr_t (m_storage) + Memory::cacheLineAlignMask)
& ~Memory::cacheLineAlignMask);
/*
return reinterpret_cast <T*> (Memory::pointerAdjustedForAlignment (
m_storage, Memory::cacheLineBytes));
*/
}
char m_storage [ (sizeof (T) + Memory::cacheLineAlignMask) & ~Memory::cacheLineAlignMask];
};
//------------------------------------------------------------------------------
/** End-pads an object to completely fill straddling CPU cache lines.
The caller must ensure that this object starts at the beginning
of a cache line.
*/
template <typename T>
class Padded
{
public:
Padded ()
{
}
template <class T1>
explicit Padded (T1 t1)
: m_t (t1)
{
}
template <class T1, class T2>
Padded (T1 t1, T2 t2)
: m_t (t1, t2)
{
}
template <class T1, class T2, class T3>
Padded (T1 t1, T2 t2, T3 t3)
: m_t (t1, t2, t3)
{
}
template <class T1, class T2, class T3, class T4>
Padded (T1 t1, T2 t2, T3 t3, T4 t4)
: m_t (t1, t2, t3, t4)
{
}
template <class T1, class T2, class T3, class T4, class T5>
Padded (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
: m_t (t1, t2, t3, t4, t5)
{
}
template <class T1, class T2, class T3, class T4, class T5, class T6>
Padded (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
: m_t (t1, t2, t3, t4, t5, t6)
{
}
template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
Padded (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7)
: m_t (t1, t2, t3, t4, t5, t6, t7)
{
}
template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
Padded (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
: m_t (t1, t2, t3, t4, t5, t6, t7, t8)
{
}
T& operator= (T const& other)
{
m_t = other;
return m_t;
}
T& get() noexcept { return m_t;}
T& operator* () noexcept { return get(); }
T* operator-> () noexcept { return &get(); }
operator T& () noexcept { return get(); }
operator T* () noexcept { return &get(); }
T const& get () const noexcept { return m_t; }
const T& operator* () const noexcept { return get(); }
const T* operator-> () const noexcept { return &get(); }
operator T const& () const noexcept { return get(); }
operator T const* () const noexcept { return &get(); }
private:
T m_t;
char pad [Memory::cacheLineAlignBytes - sizeof (T)];
};
#else
template <typename T>
class Aligned
{
public:
Aligned ()
{ }
template <class T1>
explicit Aligned (const T1& t1)
: m_t (t1) { }
template <class T1, class T2>
Aligned (const T1& t1, const T2& t2)
: m_t (t1, t2) { }
template <class T1, class T2, class T3>
Aligned (const T1& t1, const T2& t2, const T3& t3)
: m_t (t1, t2, t3) { }
template <class T1, class T2, class T3, class T4>
Aligned (const T1& t1, const T2& t2, const T3& t3, const T4& t4)
: m_t (t1, t2, t3, t4) { }
template <class T1, class T2, class T3, class T4, class T5>
Aligned (const T1& t1, const T2& t2, const T3& t3,
const T4& t4, const T5& t5)
: m_t (t1, t2, t3, t4, t5) { }
template <class T1, class T2, class T3, class T4, class T5, class T6>
Aligned (const T1& t1, const T2& t2, const T3& t3,
const T4& t4, const T5& t5, const T6& t6)
: m_t (t1, t2, t3, t4, t5, t6) { }
template < class T1, class T2, class T3, class T4,
class T5, class T6, class T7 >
Aligned (const T1& t1, const T2& t2, const T3& t3, const T4& t4,
const T5& t5, const T6& t6, const T7& t7)
: m_t (t1, t2, t3, t4, t5, t6, t7) { }
template < class T1, class T2, class T3, class T4,
class T5, class T6, class T7, class T8 >
Aligned (const T1& t1, const T2& t2, const T3& t3, const T4& t4,
const T5& t5, const T6& t6, const T7& t7, const T8& t8)
: m_t (t1, t2, t3, t4, t5, t6, t7, t8) { }
T& operator= (const T& other)
{
reutrn (m_t = other);
}
T& get () noexcept { return m_t; }
T& operator* () noexcept { return get(); }
T* operator-> () noexcept { return &get(); }
operator T& () noexcept { return get(); }
operator T* () noexcept { return &get(); }
T const& get () const noexcept { return m_t; }
const T& operator* () const noexcept { return get(); }
const T* operator-> () const noexcept { return &get(); }
operator T const& () const noexcept { return get(); }
operator T const* () const noexcept { return &get(); }
private:
T m_t;
};
template <typename T>
class Padded
{
public:
Padded ()
{ }
template <class T1>
explicit Padded (const T1& t1)
: m_t (t1) { }
template <class T1, class T2>
Padded (const T1& t1, const T2& t2)
: m_t (t1, t2) { }
template <class T1, class T2, class T3>
Padded (const T1& t1, const T2& t2, const T3& t3)
: m_t (t1, t2, t3) { }
template <class T1, class T2, class T3, class T4>
Padded (const T1& t1, const T2& t2, const T3& t3, const T4& t4)
: m_t (t1, t2, t3, t4) { }
template <class T1, class T2, class T3, class T4, class T5>
Padded (const T1& t1, const T2& t2, const T3& t3,
const T4& t4, const T5& t5)
: m_t (t1, t2, t3, t4, t5) { }
template <class T1, class T2, class T3, class T4, class T5, class T6>
Padded (const T1& t1, const T2& t2, const T3& t3,
const T4& t4, const T5& t5, const T6& t6)
: m_t (t1, t2, t3, t4, t5, t6) { }
template < class T1, class T2, class T3, class T4,
class T5, class T6, class T7 >
Padded (const T1& t1, const T2& t2, const T3& t3, const T4& t4,
const T5& t5, const T6& t6, const T7& t7)
: m_t (t1, t2, t3, t4, t5, t6, t7) { }
template < class T1, class T2, class T3, class T4,
class T5, class T6, class T7, class T8 >
Padded (const T1& t1, const T2& t2, const T3& t3, const T4& t4,
const T5& t5, const T6& t6, const T7& t7, const T8& t8)
: m_t (t1, t2, t3, t4, t5, t6, t7, t8) { }
void operator= (const T& other)
{
m_t = other;
}
T& get () noexcept { return m_t; }
T& operator* () noexcept { return get(); }
T* operator-> () noexcept { return &get(); }
operator T& () noexcept { return get(); }
operator T* () noexcept { return &get(); }
T const& get () const noexcept { return m_t; }
const T& operator* () const noexcept { return get(); }
const T* operator-> () const noexcept { return &get(); }
operator T const& () const noexcept { return get(); }
operator T const* () const noexcept { return &get(); }
private:
T m_t;
};
#endif
//
// Used to remove padding without changing code
//
template <typename T>
class Unpadded
{
public:
Unpadded ()
{ }
template <class T1>
explicit Unpadded (const T1& t1)
: m_t (t1) { }
template <class T1, class T2>
Unpadded (const T1& t1, const T2& t2)
: m_t (t1, t2) { }
template <class T1, class T2, class T3>
Unpadded (const T1& t1, const T2& t2, const T3& t3)
: m_t (t1, t2, t3) { }
template <class T1, class T2, class T3, class T4>
Unpadded (const T1& t1, const T2& t2, const T3& t3, const T4& t4)
: m_t (t1, t2, t3, t4) { }
template <class T1, class T2, class T3, class T4, class T5>
Unpadded (const T1& t1, const T2& t2, const T3& t3,
const T4& t4, const T5& t5)
: m_t (t1, t2, t3, t4, t5) { }
template <class T1, class T2, class T3, class T4, class T5, class T6>
Unpadded (const T1& t1, const T2& t2, const T3& t3,
const T4& t4, const T5& t5, const T6& t6)
: m_t (t1, t2, t3, t4, t5, t6) { }
template < class T1, class T2, class T3, class T4,
class T5, class T6, class T7 >
Unpadded (const T1& t1, const T2& t2, const T3& t3, const T4& t4,
const T5& t5, const T6& t6, const T7& t7)
: m_t (t1, t2, t3, t4, t5, t6, t7) { }
template < class T1, class T2, class T3, class T4,
class T5, class T6, class T7, class T8 >
Unpadded (const T1& t1, const T2& t2, const T3& t3, const T4& t4,
const T5& t5, const T6& t6, const T7& t7, const T8& t8)
: m_t (t1, t2, t3, t4, t5, t6, t7, t8) { }
T* operator= (const T& other)
{
return (m_t = other);
}
T& get () noexcept { return m_t; }
T& operator* () noexcept { return get(); }
T* operator-> () noexcept { return &get(); }
operator T& () noexcept { return get(); }
operator T* () noexcept { return &get(); }
T const& get () const noexcept { return m_t; }
const T& operator* () const noexcept { return get(); }
const T* operator-> () const noexcept { return &get(); }
operator T const& () const noexcept { return get(); }
operator T const* () const noexcept { return &get(); }
private:
T m_t;
};
} // namespace CacheLine
} // namespace beast
#endif

View File

@@ -1,72 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_MEMORYALIGNMENT_H_INCLUDED
#define BEAST_MEMORYALIGNMENT_H_INCLUDED
namespace beast
{
namespace Memory
{
//------------------------------------------------------------------------------
// Constants
//
// These need to be set based on the target CPU
//
const int cacheLineAlignBits = 6; // 64 bytes
const int cacheLineAlignBytes = 1 << cacheLineAlignBits;
const int cacheLineAlignMask = cacheLineAlignBytes - 1;
const int allocAlignBits = 3; // 8 bytes
const int allocAlignBytes = 1 << allocAlignBits;
const int allocAlignMask = allocAlignBytes - 1;
//------------------------------------------------------------------------------
// Returns the number of bytes needed to advance p to the correct alignment
template <typename P>
inline size_t bytesNeededForAlignment (P const* const p)
{
return (allocAlignBytes - (uintptr_t (p) & allocAlignMask))
& allocAlignMask;
}
// Returns the number of bytes to make "bytes" an aligned size
inline size_t sizeAdjustedForAlignment (const size_t bytes)
{
return (bytes + allocAlignMask) & ~allocAlignMask;
}
// Returns a pointer with alignment added.
template <typename P>
inline P* pointerAdjustedForAlignment (P* const p)
{
return reinterpret_cast <P*> (reinterpret_cast <char*> (p) +
bytesNeededForAlignment (p));
}
} // namespace Memory
} // namespace beast
#endif

View File

@@ -1,184 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_OPTIONALSCOPEDPOINTER_H_INCLUDED
#define BEAST_OPTIONALSCOPEDPOINTER_H_INCLUDED
namespace beast
{
//==============================================================================
/**
Holds a pointer to an object which can optionally be deleted when this pointer
goes out of scope.
This acts in many ways like a ScopedPointer, but allows you to specify whether or
not the object is deleted.
@see ScopedPointer
*/
template <class ObjectType>
class OptionalScopedPointer
{
public:
//==============================================================================
/** Creates an empty OptionalScopedPointer. */
OptionalScopedPointer() : shouldDelete (false) {}
/** Creates an OptionalScopedPointer to point to a given object, and specifying whether
the OptionalScopedPointer will delete it.
If takeOwnership is true, then the OptionalScopedPointer will act like a ScopedPointer,
deleting the object when it is itself deleted. If this parameter is false, then the
OptionalScopedPointer just holds a normal pointer to the object, and won't delete it.
*/
OptionalScopedPointer (ObjectType* objectToHold, bool takeOwnership)
: object (objectToHold), shouldDelete (takeOwnership)
{
}
/** Takes ownership of the object that another OptionalScopedPointer holds.
Like a normal ScopedPointer, the objectToTransferFrom object will become null,
as ownership of the managed object is transferred to this object.
The flag to indicate whether or not to delete the managed object is also
copied from the source object.
*/
OptionalScopedPointer (OptionalScopedPointer& objectToTransferFrom)
: object (objectToTransferFrom.release()),
shouldDelete (objectToTransferFrom.shouldDelete)
{
}
/** Takes ownership of the object that another OptionalScopedPointer holds.
Like a normal ScopedPointer, the objectToTransferFrom object will become null,
as ownership of the managed object is transferred to this object.
The ownership flag that says whether or not to delete the managed object is also
copied from the source object.
*/
OptionalScopedPointer& operator= (OptionalScopedPointer& objectToTransferFrom)
{
if (object != objectToTransferFrom.object)
{
clear();
object = objectToTransferFrom.object;
}
shouldDelete = objectToTransferFrom.shouldDelete;
return *this;
}
/** The destructor may or may not delete the object that is being held, depending on the
takeOwnership flag that was specified when the object was first passed into an
OptionalScopedPointer constructor.
*/
~OptionalScopedPointer()
{
clear();
}
//==============================================================================
/** Returns the object that this pointer is managing. */
inline operator ObjectType*() const noexcept { return object; }
/** Returns the object that this pointer is managing. */
inline ObjectType* get() const noexcept { return object; }
/** Returns the object that this pointer is managing. */
inline ObjectType& operator*() const noexcept { return *object; }
/** Lets you access methods and properties of the object that this pointer is holding. */
inline ObjectType* operator->() const noexcept { return object; }
//==============================================================================
/** Removes the current object from this OptionalScopedPointer without deleting it.
This will return the current object, and set this OptionalScopedPointer to a null pointer.
*/
ObjectType* release() noexcept { return object.release(); }
/** Resets this pointer to null, possibly deleting the object that it holds, if it has
ownership of it.
*/
void clear()
{
if (! shouldDelete)
object.release();
}
/** Makes this OptionalScopedPointer point at a new object, specifying whether the
OptionalScopedPointer will take ownership of the object.
If takeOwnership is true, then the OptionalScopedPointer will act like a ScopedPointer,
deleting the object when it is itself deleted. If this parameter is false, then the
OptionalScopedPointer just holds a normal pointer to the object, and won't delete it.
*/
void set (ObjectType* newObject, bool takeOwnership)
{
if (object != newObject)
{
clear();
object = newObject;
}
shouldDelete = takeOwnership;
}
/** Makes this OptionalScopedPointer point at a new object, and take ownership of that object. */
void setOwned (ObjectType* newObject)
{
set (newObject, true);
}
/** Makes this OptionalScopedPointer point at a new object, but will not take ownership of that object. */
void setNonOwned (ObjectType* newObject)
{
set (newObject, false);
}
/** Returns true if the target object will be deleted when this pointer
object is deleted.
*/
bool willDeleteObject() const noexcept { return shouldDelete; }
//==============================================================================
/** Swaps this object with another OptionalScopedPointer.
The two objects simply exchange their states.
*/
void swapWith (OptionalScopedPointer<ObjectType>& other) noexcept
{
object.swapWith (other.object);
std::swap (shouldDelete, other.shouldDelete);
}
private:
//==============================================================================
ScopedPointer<ObjectType> object;
bool shouldDelete;
};
} // namespace beast
#endif // BEAST_OPTIONALSCOPEDPOINTER_H_INCLUDED

View File

@@ -1,114 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace beast
{
namespace
{
int64 getRandomSeedFromMACAddresses()
{
Array<MACAddress> result;
MACAddress::findAllAddresses (result);
Random r;
for (int i = 0; i < result.size(); ++i)
r.combineSeed (result[i].toInt64());
return r.nextInt64();
}
}
//==============================================================================
Uuid::Uuid()
{
// The normal random seeding is pretty good, but we'll throw some MAC addresses
// into the mix too, to make it very very unlikely that two UUIDs will ever be the same..
static Random r1 (getRandomSeedFromMACAddresses());
Random r2;
for (size_t i = 0; i < sizeof (uuid); ++i)
uuid[i] = (uint8) (r1.nextInt() ^ r2.nextInt());
}
Uuid::~Uuid() noexcept {}
Uuid::Uuid (const Uuid& other) noexcept
{
memcpy (uuid, other.uuid, sizeof (uuid));
}
Uuid& Uuid::operator= (const Uuid& other) noexcept
{
memcpy (uuid, other.uuid, sizeof (uuid));
return *this;
}
bool Uuid::operator== (const Uuid& other) const noexcept { return memcmp (uuid, other.uuid, sizeof (uuid)) == 0; }
bool Uuid::operator!= (const Uuid& other) const noexcept { return ! operator== (other); }
bool Uuid::isNull() const noexcept
{
for (size_t i = 0; i < sizeof (uuid); ++i)
if (uuid[i] != 0)
return false;
return true;
}
String Uuid::toString() const
{
return String::toHexString (uuid, sizeof (uuid), 0);
}
Uuid::Uuid (const String& uuidString)
{
operator= (uuidString);
}
Uuid& Uuid::operator= (const String& uuidString)
{
MemoryBlock mb;
mb.loadFromHexString (uuidString);
mb.ensureSize (sizeof (uuid), true);
mb.copyTo (uuid, 0, sizeof (uuid));
return *this;
}
Uuid::Uuid (const uint8* const rawData)
{
operator= (rawData);
}
Uuid& Uuid::operator= (const uint8* const rawData) noexcept
{
if (rawData != nullptr)
memcpy (uuid, rawData, sizeof (uuid));
else
zeromem (uuid, sizeof (uuid));
return *this;
}
} // namespace beast

View File

@@ -1,108 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_UUID_H_INCLUDED
#define BEAST_UUID_H_INCLUDED
namespace beast
{
//==============================================================================
/**
A universally unique 128-bit identifier.
This class generates very random unique numbers based on the system time
and MAC addresses if any are available. It's extremely unlikely that two identical
UUIDs would ever be created by chance.
The class includes methods for saving the ID as a string or as raw binary data.
*/
class BEAST_API Uuid : LeakChecked <Uuid>
{
public:
//==============================================================================
/** Creates a new unique ID. */
Uuid();
/** Destructor. */
~Uuid() noexcept;
/** Creates a copy of another UUID. */
Uuid (const Uuid& other) noexcept;
/** Copies another UUID. */
Uuid& operator= (const Uuid& other) noexcept;
//==============================================================================
/** Returns true if the ID is zero. */
bool isNull() const noexcept;
bool operator== (const Uuid& other) const noexcept;
bool operator!= (const Uuid& other) const noexcept;
//==============================================================================
/** Returns a stringified version of this UUID.
A Uuid object can later be reconstructed from this string using operator= or
the constructor that takes a string parameter.
@returns a 32 character hex string.
*/
String toString() const;
/** Creates an ID from an encoded string version.
@see toString
*/
Uuid (const String& uuidString);
/** Copies from a stringified UUID.
The string passed in should be one that was created with the toString() method.
*/
Uuid& operator= (const String& uuidString);
//==============================================================================
/** Returns a pointer to the internal binary representation of the ID.
This is an array of 16 bytes. To reconstruct a Uuid from its data, use
the constructor or operator= method that takes an array of uint8s.
*/
const uint8* getRawData() const noexcept { return uuid; }
/** Creates a UUID from a 16-byte array.
@see getRawData
*/
Uuid (const uint8* rawData);
/** Sets this UUID from 16-bytes of raw data. */
Uuid& operator= (const uint8* rawData) noexcept;
private:
//==============================================================================
uint8 uuid[16];
};
} // namespace beast
#endif // BEAST_UUID_H_INCLUDED

View File

@@ -1,240 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace beast
{
bool File::copyInternal (const File& dest) const
{
FileInputStream in (*this);
if (dest.deleteFile())
{
{
FileOutputStream out (dest);
if (out.failedToOpen())
return false;
if (out.writeFromInputStream (in, -1) == getSize())
return true;
}
dest.deleteFile();
}
return false;
}
void File::findFileSystemRoots (Array<File>& destArray)
{
destArray.add (File ("/"));
}
//==============================================================================
bool File::isOnCDRomDrive() const
{
return false;
}
bool File::isOnHardDisk() const
{
return true;
}
bool File::isOnRemovableDrive() const
{
return false;
}
bool File::isHidden() const
{
return getFileName().startsWithChar ('.');
}
//==============================================================================
namespace
{
File beast_readlink (const String& file, const File& defaultFile)
{
const int size = 8192;
HeapBlock<char> buffer;
buffer.malloc (size + 4);
const size_t numBytes = readlink (file.toUTF8(), buffer, size);
if (numBytes > 0 && numBytes <= size)
return File (file).getSiblingFile (String::fromUTF8 (buffer, (int) numBytes));
return defaultFile;
}
}
File File::getLinkedTarget() const
{
return beast_readlink (getFullPathName().toUTF8(), *this);
}
//==============================================================================
File File::getSpecialLocation (const SpecialLocationType type)
{
switch (type)
{
case userHomeDirectory:
case userDocumentsDirectory:
case userMusicDirectory:
case userMoviesDirectory:
case userPicturesDirectory:
case userApplicationDataDirectory:
case commonDocumentsDirectory:
case userDesktopDirectory:
return File (android.appDataDir);
case commonApplicationDataDirectory:
return File (android.appDataDir);
case globalApplicationsDirectory:
return File ("/system/app");
case tempDirectory:
return File (android.appDataDir).getChildFile (".temp");
case invokedExecutableFile:
case currentExecutableFile:
case currentApplicationFile:
case hostApplicationPath:
return beast_getExecutableFile();
default:
bassertfalse; // unknown type?
break;
}
return File::nonexistent ();
}
//==============================================================================
String File::getVersion() const
{
return String::empty;
}
//==============================================================================
bool File::moveToTrash() const
{
if (! exists())
return true;
// TODO
return false;
}
//==============================================================================
class DirectoryIterator::NativeIterator::Pimpl : public Uncopyable
{
public:
Pimpl (const File& directory, const String& wildCard_)
: parentDir (File::addTrailingSeparator (directory.getFullPathName())),
wildCard (wildCard_),
dir (opendir (directory.getFullPathName().toUTF8()))
{
}
~Pimpl()
{
if (dir != 0)
closedir (dir);
}
bool next (String& filenameFound,
bool* const isDir, bool* const isHidden, int64* const fileSize,
Time* const modTime, Time* const creationTime, bool* const isReadOnly)
{
if (dir != 0)
{
const char* wildcardUTF8 = nullptr;
for (;;)
{
struct dirent* const de = readdir (dir);
if (de == nullptr)
break;
if (wildcardUTF8 == nullptr)
wildcardUTF8 = wildCard.toUTF8();
if (fnmatch (wildcardUTF8, de->d_name, FNM_CASEFOLD) == 0)
{
filenameFound = CharPointer_UTF8 (de->d_name);
updateStatInfoForFile (parentDir + filenameFound, isDir, fileSize, modTime, creationTime, isReadOnly);
if (isHidden != 0)
*isHidden = filenameFound.startsWithChar ('.');
return true;
}
}
}
return false;
}
private:
String parentDir, wildCard;
DIR* dir;
};
DirectoryIterator::NativeIterator::NativeIterator (const File& directory, const String& wildCard)
: pimpl (new DirectoryIterator::NativeIterator::Pimpl (directory, wildCard))
{
}
DirectoryIterator::NativeIterator::~NativeIterator()
{
}
bool DirectoryIterator::NativeIterator::next (String& filenameFound,
bool* const isDir, bool* const isHidden, int64* const fileSize,
Time* const modTime, Time* const creationTime, bool* const isReadOnly)
{
return pimpl->next (filenameFound, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly);
}
//==============================================================================
bool Process::openDocument (const String& fileName, const String& parameters)
{
const LocalRef<jstring> t (javaString (fileName));
android.activity.callVoidMethod (BeastAppActivity.launchURL, t.get());
return true;
}
void File::revealToUser() const
{
}
} // namespace beast

View File

@@ -1,405 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_ANDROID_JNIHELPERS_H_INCLUDED
#define BEAST_ANDROID_JNIHELPERS_H_INCLUDED
namespace beast
{
#if ! (defined (BEAST_ANDROID_ACTIVITY_CLASSNAME) && defined (BEAST_ANDROID_ACTIVITY_CLASSPATH))
#error "The BEAST_ANDROID_ACTIVITY_CLASSNAME and BEAST_ANDROID_ACTIVITY_CLASSPATH macros must be set!"
#endif
//==============================================================================
extern JNIEnv* getEnv() noexcept;
//==============================================================================
class GlobalRef
{
public:
inline GlobalRef() noexcept : obj (0) {}
inline explicit GlobalRef (jobject o) : obj (retain (o)) {}
inline GlobalRef (const GlobalRef& other) : obj (retain (other.obj)) {}
~GlobalRef() { clear(); }
inline void clear()
{
if (obj != 0)
{
getEnv()->DeleteGlobalRef (obj);
obj = 0;
}
}
inline GlobalRef& operator= (const GlobalRef& other)
{
jobject newObj = retain (other.obj);
clear();
obj = newObj;
return *this;
}
//==============================================================================
inline operator jobject() const noexcept { return obj; }
inline jobject get() const noexcept { return obj; }
//==============================================================================
#define DECLARE_CALL_TYPE_METHOD(returnType, typeName) \
returnType call##typeName##Method (jmethodID methodID, ... ) const \
{ \
va_list args; \
va_start (args, methodID); \
returnType result = getEnv()->Call##typeName##MethodV (obj, methodID, args); \
va_end (args); \
return result; \
}
DECLARE_CALL_TYPE_METHOD (jobject, Object)
DECLARE_CALL_TYPE_METHOD (jboolean, Boolean)
DECLARE_CALL_TYPE_METHOD (jbyte, Byte)
DECLARE_CALL_TYPE_METHOD (jchar, Char)
DECLARE_CALL_TYPE_METHOD (jshort, Short)
DECLARE_CALL_TYPE_METHOD (jint, Int)
DECLARE_CALL_TYPE_METHOD (jlong, Long)
DECLARE_CALL_TYPE_METHOD (jfloat, Float)
DECLARE_CALL_TYPE_METHOD (jdouble, Double)
#undef DECLARE_CALL_TYPE_METHOD
void callVoidMethod (jmethodID methodID, ... ) const
{
va_list args;
va_start (args, methodID);
getEnv()->CallVoidMethodV (obj, methodID, args);
va_end (args);
}
private:
//==============================================================================
jobject obj;
static inline jobject retain (jobject obj)
{
return obj == 0 ? 0 : getEnv()->NewGlobalRef (obj);
}
};
//==============================================================================
template <typename JavaType>
class LocalRef
{
public:
explicit inline LocalRef (JavaType o) noexcept : obj (o) {}
inline LocalRef (const LocalRef& other) noexcept : obj (retain (other.obj)) {}
~LocalRef() { clear(); }
void clear()
{
if (obj != 0)
getEnv()->DeleteLocalRef (obj);
}
LocalRef& operator= (const LocalRef& other)
{
jobject newObj = retain (other.obj);
clear();
obj = newObj;
return *this;
}
inline operator JavaType() const noexcept { return obj; }
inline JavaType get() const noexcept { return obj; }
private:
JavaType obj;
static JavaType retain (JavaType obj)
{
return obj == 0 ? 0 : (JavaType) getEnv()->NewLocalRef (obj);
}
};
//==============================================================================
namespace
{
String beastString (JNIEnv* env, jstring s)
{
const char* const utf8 = env->GetStringUTFChars (s, nullptr);
CharPointer_UTF8 utf8CP (utf8);
const String result (utf8CP);
env->ReleaseStringUTFChars (s, utf8);
return result;
}
String beastString (jstring s)
{
return beastString (getEnv(), s);
}
LocalRef<jstring> javaString (const String& s)
{
return LocalRef<jstring> (getEnv()->NewStringUTF (s.toUTF8()));
}
LocalRef<jstring> javaStringFromChar (const beast_wchar c)
{
char utf8[8] = { 0 };
CharPointer_UTF8 (utf8).write (c);
return LocalRef<jstring> (getEnv()->NewStringUTF (utf8));
}
}
//==============================================================================
class JNIClassBase : public Uncopyable
{
public:
explicit JNIClassBase (const char* classPath);
virtual ~JNIClassBase();
inline operator jclass() const noexcept { return classRef; }
static void initialiseAllClasses (JNIEnv*);
static void releaseAllClasses (JNIEnv*);
protected:
virtual void initialiseFields (JNIEnv*) = 0;
jmethodID resolveMethod (JNIEnv*, const char* methodName, const char* params);
jmethodID resolveStaticMethod (JNIEnv*, const char* methodName, const char* params);
jfieldID resolveField (JNIEnv*, const char* fieldName, const char* signature);
jfieldID resolveStaticField (JNIEnv*, const char* fieldName, const char* signature);
private:
const char* const classPath;
jclass classRef;
static Array<JNIClassBase*>& getClasses();
void initialise (JNIEnv*);
void release (JNIEnv*);
};
//==============================================================================
#define CREATE_JNI_METHOD(methodID, stringName, params) methodID = resolveMethod (env, stringName, params);
#define CREATE_JNI_STATICMETHOD(methodID, stringName, params) methodID = resolveStaticMethod (env, stringName, params);
#define CREATE_JNI_FIELD(fieldID, stringName, signature) fieldID = resolveField (env, stringName, signature);
#define CREATE_JNI_STATICFIELD(fieldID, stringName, signature) fieldID = resolveStaticField (env, stringName, signature);
#define DECLARE_JNI_METHOD(methodID, stringName, params) jmethodID methodID;
#define DECLARE_JNI_FIELD(fieldID, stringName, signature) jfieldID fieldID;
#define DECLARE_JNI_CLASS(CppClassName, javaPath) \
class CppClassName ## _Class : public JNIClassBase \
{ \
public: \
CppClassName ## _Class() : JNIClassBase (javaPath) {} \
\
void initialiseFields (JNIEnv* env) \
{ \
JNI_CLASS_MEMBERS (CREATE_JNI_METHOD, CREATE_JNI_STATICMETHOD, CREATE_JNI_FIELD, CREATE_JNI_STATICFIELD); \
} \
\
JNI_CLASS_MEMBERS (DECLARE_JNI_METHOD, DECLARE_JNI_METHOD, DECLARE_JNI_FIELD, DECLARE_JNI_FIELD); \
}; \
static CppClassName ## _Class CppClassName;
//==============================================================================
#define BEAST_JNI_CALLBACK(className, methodName, returnType, params) \
extern "C" __attribute__ ((visibility("default"))) returnType BEAST_JOIN_MACRO (BEAST_JOIN_MACRO (Java_, className), _ ## methodName) params
//==============================================================================
class AndroidSystem
{
public:
AndroidSystem();
void initialise (JNIEnv*, jobject activity, jstring appFile, jstring appDataDir);
void shutdown (JNIEnv*);
//==============================================================================
GlobalRef activity;
String appFile, appDataDir;
int screenWidth, screenHeight;
};
extern AndroidSystem android;
//==============================================================================
class ThreadLocalJNIEnvHolder
{
public:
ThreadLocalJNIEnvHolder()
: jvm (nullptr)
{
zeromem (threads, sizeof (threads));
zeromem (envs, sizeof (envs));
}
void initialise (JNIEnv* env)
{
// NB: the DLL can be left loaded by the JVM, so the same static
// objects can end up being reused by subsequent runs of the app
zeromem (threads, sizeof (threads));
zeromem (envs, sizeof (envs));
env->GetJavaVM (&jvm);
addEnv (env);
}
JNIEnv* attach()
{
JNIEnv* env = nullptr;
jvm->AttachCurrentThread (&env, nullptr);
if (env != nullptr)
addEnv (env);
return env;
}
void detach()
{
jvm->DetachCurrentThread();
const pthread_t thisThread = pthread_self();
SpinLock::ScopedLockType sl (addRemoveLock);
for (int i = 0; i < maxThreads; ++i)
if (threads[i] == thisThread)
threads[i] = 0;
}
JNIEnv* getOrAttach() noexcept
{
JNIEnv* env = get();
if (env == nullptr)
env = attach();
bassert (env != nullptr);
return env;
}
JNIEnv* get() const noexcept
{
const pthread_t thisThread = pthread_self();
for (int i = 0; i < maxThreads; ++i)
if (threads[i] == thisThread)
return envs[i];
return nullptr;
}
enum { maxThreads = 32 };
private:
JavaVM* jvm;
pthread_t threads [maxThreads];
JNIEnv* envs [maxThreads];
SpinLock addRemoveLock;
void addEnv (JNIEnv* env)
{
SpinLock::ScopedLockType sl (addRemoveLock);
if (get() == nullptr)
{
const pthread_t thisThread = pthread_self();
for (int i = 0; i < maxThreads; ++i)
{
if (threads[i] == 0)
{
envs[i] = env;
threads[i] = thisThread;
return;
}
}
}
bassertfalse; // too many threads!
}
};
extern ThreadLocalJNIEnvHolder threadLocalJNIEnvHolder;
//==============================================================================
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
METHOD (createNewView, "createNewView", "(Z)L" BEAST_ANDROID_ACTIVITY_CLASSPATH "$ComponentPeerView;") \
METHOD (deleteView, "deleteView", "(L" BEAST_ANDROID_ACTIVITY_CLASSPATH "$ComponentPeerView;)V") \
METHOD (postMessage, "postMessage", "(J)V") \
METHOD (finish, "finish", "()V") \
METHOD (getClipboardContent, "getClipboardContent", "()Ljava/lang/String;") \
METHOD (setClipboardContent, "setClipboardContent", "(Ljava/lang/String;)V") \
METHOD (excludeClipRegion, "excludeClipRegion", "(Landroid/graphics/Canvas;FFFF)V") \
METHOD (renderGlyph, "renderGlyph", "(CLandroid/graphics/Paint;Landroid/graphics/Matrix;Landroid/graphics/Rect;)[I") \
STATICMETHOD (createHTTPStream, "createHTTPStream", "(Ljava/lang/String;Z[BLjava/lang/String;ILjava/lang/StringBuffer;)L" BEAST_ANDROID_ACTIVITY_CLASSPATH "$HTTPStream;") \
METHOD (launchURL, "launchURL", "(Ljava/lang/String;)V") \
METHOD (showMessageBox, "showMessageBox", "(Ljava/lang/String;Ljava/lang/String;J)V") \
METHOD (showOkCancelBox, "showOkCancelBox", "(Ljava/lang/String;Ljava/lang/String;J)V") \
METHOD (showYesNoCancelBox, "showYesNoCancelBox", "(Ljava/lang/String;Ljava/lang/String;J)V") \
STATICMETHOD (getLocaleValue, "getLocaleValue", "(Z)Ljava/lang/String;") \
METHOD (scanFile, "scanFile", "(Ljava/lang/String;)V")
DECLARE_JNI_CLASS (BeastAppActivity, BEAST_ANDROID_ACTIVITY_CLASSPATH);
#undef JNI_CLASS_MEMBERS
//==============================================================================
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
METHOD (constructor, "<init>", "(I)V") \
METHOD (setColor, "setColor", "(I)V") \
METHOD (setAlpha, "setAlpha", "(I)V") \
METHOD (setTypeface, "setTypeface", "(Landroid/graphics/Typeface;)Landroid/graphics/Typeface;") \
METHOD (ascent, "ascent", "()F") \
METHOD (descent, "descent", "()F") \
METHOD (setTextSize, "setTextSize", "(F)V") \
METHOD (getTextWidths, "getTextWidths", "(Ljava/lang/String;[F)I") \
METHOD (setTextScaleX, "setTextScaleX", "(F)V") \
METHOD (getTextPath, "getTextPath", "(Ljava/lang/String;IIFFLandroid/graphics/Path;)V") \
METHOD (setShader, "setShader", "(Landroid/graphics/Shader;)Landroid/graphics/Shader;") \
DECLARE_JNI_CLASS (Paint, "android/graphics/Paint");
#undef JNI_CLASS_MEMBERS
//==============================================================================
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
METHOD (constructor, "<init>", "()V") \
METHOD (setValues, "setValues", "([F)V") \
DECLARE_JNI_CLASS (Matrix, "android/graphics/Matrix");
#undef JNI_CLASS_MEMBERS
//==============================================================================
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
METHOD (constructor, "<init>", "(IIII)V") \
FIELD (left, "left", "I") \
FIELD (right, "right", "I") \
FIELD (top, "top", "I") \
FIELD (bottom, "bottom", "I") \
DECLARE_JNI_CLASS (RectClass, "android/graphics/Rect");
#undef JNI_CLASS_MEMBERS
} // namespace beast
#endif // BEAST_ANDROID_JNIHELPERS_H_INCLUDED

View File

@@ -1,32 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace beast
{
void Logger::outputDebugString (const String& text)
{
__android_log_print (ANDROID_LOG_INFO, "BEAST", "%", text.toUTF8().getAddress());
}
} // namespace beast

View File

@@ -1,64 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace beast
{
//==============================================================================
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
METHOD (constructor, "<init>", "()V") \
METHOD (toString, "toString", "()Ljava/lang/String;") \
DECLARE_JNI_CLASS (StringBuffer, "java/lang/StringBuffer");
#undef JNI_CLASS_MEMBERS
//==============================================================================
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
METHOD (release, "release", "()V") \
METHOD (read, "read", "([BI)I") \
METHOD (getPosition, "getPosition", "()J") \
METHOD (getTotalLength, "getTotalLength", "()J") \
METHOD (isExhausted, "isExhausted", "()Z") \
METHOD (setPosition, "setPosition", "(J)Z") \
DECLARE_JNI_CLASS (HTTPStream, BEAST_ANDROID_ACTIVITY_CLASSPATH "$HTTPStream");
#undef JNI_CLASS_MEMBERS
//==============================================================================
void MACAddress::findAllAddresses (Array<MACAddress>& result)
{
// TODO
}
bool Process::openEmailWithAttachments (const String& targetEmailAddress,
const String& emailSubject,
const String& bodyText,
const StringArray& filesToAttach)
{
// TODO
return false;
}
} // namespace beast

View File

@@ -1,306 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace beast
{
JNIClassBase::JNIClassBase (const char* classPath_)
: classPath (classPath_), classRef (0)
{
getClasses().add (this);
}
JNIClassBase::~JNIClassBase()
{
getClasses().removeFirstMatchingValue (this);
}
Array<JNIClassBase*>& JNIClassBase::getClasses()
{
static Array<JNIClassBase*> classes;
return classes;
}
void JNIClassBase::initialise (JNIEnv* env)
{
classRef = (jclass) env->NewGlobalRef (env->FindClass (classPath));
bassert (classRef != 0);
initialiseFields (env);
}
void JNIClassBase::release (JNIEnv* env)
{
env->DeleteGlobalRef (classRef);
}
void JNIClassBase::initialiseAllClasses (JNIEnv* env)
{
const Array<JNIClassBase*>& classes = getClasses();
for (int i = classes.size(); --i >= 0;)
classes.getUnchecked(i)->initialise (env);
}
void JNIClassBase::releaseAllClasses (JNIEnv* env)
{
const Array<JNIClassBase*>& classes = getClasses();
for (int i = classes.size(); --i >= 0;)
classes.getUnchecked(i)->release (env);
}
jmethodID JNIClassBase::resolveMethod (JNIEnv* env, const char* methodName, const char* params)
{
jmethodID m = env->GetMethodID (classRef, methodName, params);
bassert (m != 0);
return m;
}
jmethodID JNIClassBase::resolveStaticMethod (JNIEnv* env, const char* methodName, const char* params)
{
jmethodID m = env->GetStaticMethodID (classRef, methodName, params);
bassert (m != 0);
return m;
}
jfieldID JNIClassBase::resolveField (JNIEnv* env, const char* fieldName, const char* signature)
{
jfieldID f = env->GetFieldID (classRef, fieldName, signature);
bassert (f != 0);
return f;
}
jfieldID JNIClassBase::resolveStaticField (JNIEnv* env, const char* fieldName, const char* signature)
{
jfieldID f = env->GetStaticFieldID (classRef, fieldName, signature);
bassert (f != 0);
return f;
}
//==============================================================================
ThreadLocalJNIEnvHolder threadLocalJNIEnvHolder;
#if BEAST_DEBUG
static bool systemInitialised = false;
#endif
JNIEnv* getEnv() noexcept
{
#if BEAST_DEBUG
if (! systemInitialised)
{
DBG ("*** Call to getEnv() when system not initialised");
bassertfalse;
exit (0);
}
#endif
return threadLocalJNIEnvHolder.getOrAttach();
}
extern "C" jint JNI_OnLoad (JavaVM*, void*)
{
return JNI_VERSION_1_2;
}
//==============================================================================
AndroidSystem::AndroidSystem() : screenWidth (0), screenHeight (0)
{
}
void AndroidSystem::initialise (JNIEnv* env, jobject activity_,
jstring appFile_, jstring appDataDir_)
{
screenWidth = screenHeight = 0;
JNIClassBase::initialiseAllClasses (env);
threadLocalJNIEnvHolder.initialise (env);
#if BEAST_DEBUG
systemInitialised = true;
#endif
activity = GlobalRef (activity_);
appFile = beastString (env, appFile_);
appDataDir = beastString (env, appDataDir_);
}
void AndroidSystem::shutdown (JNIEnv* env)
{
activity.clear();
#if BEAST_DEBUG
systemInitialised = false;
#endif
JNIClassBase::releaseAllClasses (env);
}
AndroidSystem android;
//==============================================================================
namespace AndroidStatsHelpers
{
//==============================================================================
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
STATICMETHOD (getProperty, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;")
DECLARE_JNI_CLASS (SystemClass, "java/lang/System");
#undef JNI_CLASS_MEMBERS
//==============================================================================
String getSystemProperty (const String& name)
{
return beastString (LocalRef<jstring> ((jstring) getEnv()->CallStaticObjectMethod (SystemClass,
SystemClass.getProperty,
javaString (name).get())));
}
//==============================================================================
String getLocaleValue (bool isRegion)
{
return beastString (LocalRef<jstring> ((jstring) getEnv()->CallStaticObjectMethod (BeastAppActivity,
BeastAppActivity.getLocaleValue,
isRegion)));
}
}
//==============================================================================
SystemStats::OperatingSystemType SystemStats::getOperatingSystemType()
{
return Android;
}
String SystemStats::getOperatingSystemName()
{
return "Android " + AndroidStatsHelpers::getSystemProperty ("os.version");
}
bool SystemStats::isOperatingSystem64Bit()
{
#if BEAST_64BIT
return true;
#else
return false;
#endif
}
String SystemStats::getCpuVendor()
{
return AndroidStatsHelpers::getSystemProperty ("os.arch");
}
int SystemStats::getCpuSpeedInMegaherz()
{
return 0; // TODO
}
int SystemStats::getMemorySizeInMegabytes()
{
#if __ANDROID_API__ >= 9
struct sysinfo sysi;
if (sysinfo (&sysi) == 0)
return (sysi.totalram * sysi.mem_unit / (1024 * 1024));
#endif
return 0;
}
int SystemStats::getPageSize()
{
return sysconf (_SC_PAGESIZE);
}
//==============================================================================
String SystemStats::getLogonName()
{
const char* user = getenv ("USER");
if (user == 0)
{
struct passwd* const pw = getpwuid (getuid());
if (pw != 0)
user = pw->pw_name;
}
return CharPointer_UTF8 (user);
}
String SystemStats::getFullUserName()
{
return getLogonName();
}
String SystemStats::getComputerName()
{
char name [256] = { 0 };
if (gethostname (name, sizeof (name) - 1) == 0)
return name;
return String::empty;
}
String SystemStats::getUserLanguage() { return AndroidStatsHelpers::getLocaleValue (false); }
String SystemStats::getUserRegion() { return AndroidStatsHelpers::getLocaleValue (true); }
String SystemStats::getDisplayLanguage() { return getUserLanguage(); }
//==============================================================================
void CPUInformation::initialise() noexcept
{
numCpus = bmax (1, sysconf (_SC_NPROCESSORS_ONLN));
}
//==============================================================================
uint32 beast_millisecondsSinceStartup() noexcept
{
timespec t;
clock_gettime (CLOCK_MONOTONIC, &t);
return t.tv_sec * 1000 + t.tv_nsec / 1000000;
}
int64 Time::getHighResolutionTicks() noexcept
{
timespec t;
clock_gettime (CLOCK_MONOTONIC, &t);
return (t.tv_sec * (int64) 1000000) + (t.tv_nsec / 1000);
}
int64 Time::getHighResolutionTicksPerSecond() noexcept
{
return 1000000; // (microseconds)
}
double Time::getMillisecondCounterHiRes() noexcept
{
return getHighResolutionTicks() * 0.001;
}
bool Time::setSystemTimeToThisTime() const
{
bassertfalse;
return false;
}
} // namespace beast

View File

@@ -1,76 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace beast
{
/*
Note that a lot of methods that you'd expect to find in this file actually
live in beast_posix_SharedCode.h!
*/
//==============================================================================
// sets the process to 0=low priority, 1=normal, 2=high, 3=realtime
void Process::setPriority (ProcessPriority prior)
{
// TODO
struct sched_param param;
int policy, maxp, minp;
const int p = (int) prior;
if (p <= 1)
policy = SCHED_OTHER;
else
policy = SCHED_RR;
minp = sched_get_priority_min (policy);
maxp = sched_get_priority_max (policy);
if (p < 2)
param.sched_priority = 0;
else if (p == 2 )
// Set to middle of lower realtime priority range
param.sched_priority = minp + (maxp - minp) / 4;
else
// Set to middle of higher realtime priority range
param.sched_priority = minp + (3 * (maxp - minp) / 4);
pthread_setschedparam (pthread_self(), policy, &param);
}
bool beast_isRunningUnderDebugger()
{
return false;
}
BEAST_API bool BEAST_CALLTYPE Process::isRunningUnderDebugger()
{
return beast_isRunningUnderDebugger();
}
void Process::raisePrivilege() {}
void Process::lowerPrivilege() {}
} // namespace beast

View File

@@ -24,33 +24,6 @@
namespace beast
{
void MACAddress::findAllAddresses (Array<MACAddress>& result)
{
ifaddrs* addrs = nullptr;
if (getifaddrs (&addrs) == 0)
{
for (const ifaddrs* cursor = addrs; cursor != nullptr; cursor = cursor->ifa_next)
{
sockaddr_storage* sto = (sockaddr_storage*) cursor->ifa_addr;
if (sto->ss_family == AF_LINK)
{
const sockaddr_dl* const sadd = (const sockaddr_dl*) cursor->ifa_addr;
#ifndef IFT_ETHER
#define IFT_ETHER 6
#endif
if (sadd->sdl_type == IFT_ETHER)
result.addIfNotAlreadyThere (MACAddress (((const uint8*) sadd->sdl_data) + sadd->sdl_nlen));
}
}
freeifaddrs (addrs);
}
}
bool Process::openEmailWithAttachments (const String& /* targetEmailAddress */,
const String& /* emailSubject */,
const String& /* bodyText */,

View File

@@ -1,697 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
package com.beast;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.view.*;
import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.graphics.*;
import android.opengl.*;
import android.text.ClipboardManager;
import android.text.InputType;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.HttpURLConnection;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.media.MediaScannerConnection;
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
//==============================================================================
public final class BeastAppActivity extends Activity
{
//==============================================================================
static
{
System.loadLibrary ("beast_jni");
}
@Override
public final void onCreate (Bundle savedInstanceState)
{
super.onCreate (savedInstanceState);
viewHolder = new ViewHolder (this);
setContentView (viewHolder);
setVolumeControlStream (AudioManager.STREAM_MUSIC);
}
@Override
protected final void onDestroy()
{
quitApp();
super.onDestroy();
}
@Override
protected final void onPause()
{
if (viewHolder != null)
viewHolder.onPause();
suspendApp();
super.onPause();
}
@Override
protected final void onResume()
{
super.onResume();
if (viewHolder != null)
viewHolder.onResume();
resumeApp();
}
@Override
public void onConfigurationChanged (Configuration cfg)
{
super.onConfigurationChanged (cfg);
setContentView (viewHolder);
}
private void callAppLauncher()
{
launchApp (getApplicationInfo().publicSourceDir,
getApplicationInfo().dataDir);
}
//==============================================================================
private native void launchApp (String appFile, String appDataDir);
private native void quitApp();
private native void suspendApp();
private native void resumeApp();
private native void setScreenSize (int screenWidth, int screenHeight);
//==============================================================================
public native void deliverMessage (long value);
private android.os.Handler messageHandler = new android.os.Handler();
public final void postMessage (long value)
{
messageHandler.post (new MessageCallback (value));
}
private final class MessageCallback implements Runnable
{
public MessageCallback (long value_) { value = value_; }
public final void run() { deliverMessage (value); }
private long value;
}
//==============================================================================
private ViewHolder viewHolder;
public final ComponentPeerView createNewView (boolean opaque)
{
ComponentPeerView v = new ComponentPeerView (this, opaque);
viewHolder.addView (v);
return v;
}
public final void deleteView (ComponentPeerView view)
{
ViewGroup group = (ViewGroup) (view.getParent());
if (group != null)
group.removeView (view);
}
final class ViewHolder extends ViewGroup
{
public ViewHolder (Context context)
{
super (context);
setDescendantFocusability (ViewGroup.FOCUS_AFTER_DESCENDANTS);
setFocusable (false);
}
protected final void onLayout (boolean changed, int left, int top, int right, int bottom)
{
setScreenSize (getWidth(), getHeight());
if (isFirstResize)
{
isFirstResize = false;
callAppLauncher();
}
}
public final void onPause()
{
for (int i = getChildCount(); --i >= 0;)
{
View v = getChildAt (i);
if (v instanceof ComponentPeerView)
((ComponentPeerView) v).onPause();
}
}
public final void onResume()
{
for (int i = getChildCount(); --i >= 0;)
{
View v = getChildAt (i);
if (v instanceof ComponentPeerView)
((ComponentPeerView) v).onResume();
}
}
private boolean isFirstResize = true;
}
public final void excludeClipRegion (android.graphics.Canvas canvas, float left, float top, float right, float bottom)
{
canvas.clipRect (left, top, right, bottom, android.graphics.Region.Op.DIFFERENCE);
}
//==============================================================================
public final String getClipboardContent()
{
ClipboardManager clipboard = (ClipboardManager) getSystemService (CLIPBOARD_SERVICE);
return clipboard.getText().toString();
}
public final void setClipboardContent (String newText)
{
ClipboardManager clipboard = (ClipboardManager) getSystemService (CLIPBOARD_SERVICE);
clipboard.setText (newText);
}
//==============================================================================
public final void showMessageBox (String title, String message, final long callback)
{
AlertDialog.Builder builder = new AlertDialog.Builder (this);
builder.setTitle (title)
.setMessage (message)
.setCancelable (true)
.setPositiveButton ("OK", new DialogInterface.OnClickListener()
{
public void onClick (DialogInterface dialog, int id)
{
dialog.cancel();
BeastAppActivity.this.alertDismissed (callback, 0);
}
});
builder.create().show();
}
public final void showOkCancelBox (String title, String message, final long callback)
{
AlertDialog.Builder builder = new AlertDialog.Builder (this);
builder.setTitle (title)
.setMessage (message)
.setCancelable (true)
.setPositiveButton ("OK", new DialogInterface.OnClickListener()
{
public void onClick (DialogInterface dialog, int id)
{
dialog.cancel();
BeastAppActivity.this.alertDismissed (callback, 1);
}
})
.setNegativeButton ("Cancel", new DialogInterface.OnClickListener()
{
public void onClick (DialogInterface dialog, int id)
{
dialog.cancel();
BeastAppActivity.this.alertDismissed (callback, 0);
}
});
builder.create().show();
}
public final void showYesNoCancelBox (String title, String message, final long callback)
{
AlertDialog.Builder builder = new AlertDialog.Builder (this);
builder.setTitle (title)
.setMessage (message)
.setCancelable (true)
.setPositiveButton ("Yes", new DialogInterface.OnClickListener()
{
public void onClick (DialogInterface dialog, int id)
{
dialog.cancel();
BeastAppActivity.this.alertDismissed (callback, 1);
}
})
.setNegativeButton ("No", new DialogInterface.OnClickListener()
{
public void onClick (DialogInterface dialog, int id)
{
dialog.cancel();
BeastAppActivity.this.alertDismissed (callback, 2);
}
})
.setNeutralButton ("Cancel", new DialogInterface.OnClickListener()
{
public void onClick (DialogInterface dialog, int id)
{
dialog.cancel();
BeastAppActivity.this.alertDismissed (callback, 0);
}
});
builder.create().show();
}
public native void alertDismissed (long callback, int id);
//==============================================================================
public final class ComponentPeerView extends ViewGroup
implements View.OnFocusChangeListener
{
public ComponentPeerView (Context context, boolean opaque_)
{
super (context);
setWillNotDraw (false);
opaque = opaque_;
setFocusable (true);
setFocusableInTouchMode (true);
setOnFocusChangeListener (this);
requestFocus();
}
//==============================================================================
private native void handlePaint (Canvas canvas);
@Override
public void draw (Canvas canvas)
{
super.draw (canvas);
handlePaint (canvas);
}
@Override
public boolean isOpaque()
{
return opaque;
}
private boolean opaque;
//==============================================================================
private native void handleMouseDown (int index, float x, float y, long time);
private native void handleMouseDrag (int index, float x, float y, long time);
private native void handleMouseUp (int index, float x, float y, long time);
@Override
public boolean onTouchEvent (MotionEvent event)
{
int action = event.getAction();
long time = event.getEventTime();
switch (action & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN:
handleMouseDown (event.getPointerId(0), event.getX(), event.getY(), time);
return true;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
handleMouseUp (event.getPointerId(0), event.getX(), event.getY(), time);
return true;
case MotionEvent.ACTION_MOVE:
{
int n = event.getPointerCount();
for (int i = 0; i < n; ++i)
handleMouseDrag (event.getPointerId(i), event.getX(i), event.getY(i), time);
return true;
}
case MotionEvent.ACTION_POINTER_UP:
{
int i = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
handleMouseUp (event.getPointerId(i), event.getX(i), event.getY(i), time);
return true;
}
case MotionEvent.ACTION_POINTER_DOWN:
{
int i = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
handleMouseDown (event.getPointerId(i), event.getX(i), event.getY(i), time);
return true;
}
default:
break;
}
return false;
}
//==============================================================================
private native void handleKeyDown (int keycode, int textchar);
private native void handleKeyUp (int keycode, int textchar);
public void showKeyboard (boolean shouldShow)
{
InputMethodManager imm = (InputMethodManager) getSystemService (Context.INPUT_METHOD_SERVICE);
if (imm != null)
{
if (shouldShow)
imm.showSoftInput (this, InputMethodManager.SHOW_FORCED);
else
imm.hideSoftInputFromWindow (getWindowToken(), 0);
}
}
@Override
public boolean onKeyDown (int keyCode, KeyEvent event)
{
handleKeyDown (keyCode, event.getUnicodeChar());
return true;
}
@Override
public boolean onKeyUp (int keyCode, KeyEvent event)
{
handleKeyUp (keyCode, event.getUnicodeChar());
return true;
}
// this is here to make keyboard entry work on a Galaxy Tab2 10.1
@Override
public InputConnection onCreateInputConnection (EditorInfo outAttrs)
{
outAttrs.actionLabel = "";
outAttrs.hintText = "";
outAttrs.initialCapsMode = 0;
outAttrs.initialSelEnd = outAttrs.initialSelStart = -1;
outAttrs.label = "";
outAttrs.imeOptions = EditorInfo.IME_ACTION_DONE | EditorInfo.IME_FLAG_NO_EXTRACT_UI;
outAttrs.inputType = InputType.TYPE_NULL;
return new BaseInputConnection (this, false);
}
//==============================================================================
@Override
protected void onSizeChanged (int w, int h, int oldw, int oldh)
{
super.onSizeChanged (w, h, oldw, oldh);
viewSizeChanged();
}
@Override
protected void onLayout (boolean changed, int left, int top, int right, int bottom)
{
for (int i = getChildCount(); --i >= 0;)
requestTransparentRegion (getChildAt (i));
}
private native void viewSizeChanged();
@Override
public void onFocusChange (View v, boolean hasFocus)
{
if (v == this)
focusChanged (hasFocus);
}
private native void focusChanged (boolean hasFocus);
public void setViewName (String newName) {}
public boolean isVisible() { return getVisibility() == VISIBLE; }
public void setVisible (boolean b) { setVisibility (b ? VISIBLE : INVISIBLE); }
public boolean containsPoint (int x, int y)
{
return true; //xxx needs to check overlapping views
}
public final void onPause()
{
for (int i = getChildCount(); --i >= 0;)
{
View v = getChildAt (i);
if (v instanceof OpenGLView)
((OpenGLView) v).onPause();
}
}
public final void onResume()
{
for (int i = getChildCount(); --i >= 0;)
{
View v = getChildAt (i);
if (v instanceof OpenGLView)
((OpenGLView) v).onResume();
}
}
public OpenGLView createGLView()
{
OpenGLView glView = new OpenGLView (getContext());
addView (glView);
return glView;
}
}
//==============================================================================
public final class OpenGLView extends GLSurfaceView
implements GLSurfaceView.Renderer
{
OpenGLView (Context context)
{
super (context);
setEGLContextClientVersion (2);
setRenderer (this);
setRenderMode (RENDERMODE_WHEN_DIRTY);
}
@Override
public void onSurfaceCreated (GL10 unused, EGLConfig config)
{
contextCreated();
}
@Override
public void onSurfaceChanged (GL10 unused, int width, int height)
{
contextChangedSize();
}
@Override
public void onDrawFrame (GL10 unused)
{
render();
}
private native void contextCreated();
private native void contextChangedSize();
private native void render();
}
//==============================================================================
public final int[] renderGlyph (char glyph, Paint paint, android.graphics.Matrix matrix, Rect bounds)
{
Path p = new Path();
paint.getTextPath (String.valueOf (glyph), 0, 1, 0.0f, 0.0f, p);
RectF boundsF = new RectF();
p.computeBounds (boundsF, true);
matrix.mapRect (boundsF);
boundsF.roundOut (bounds);
bounds.left--;
bounds.right++;
final int w = bounds.width();
final int h = Math.max (1, bounds.height());
Bitmap bm = Bitmap.createBitmap (w, h, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas (bm);
matrix.postTranslate (-bounds.left, -bounds.top);
c.setMatrix (matrix);
c.drawPath (p, paint);
final int sizeNeeded = w * h;
if (cachedRenderArray.length < sizeNeeded)
cachedRenderArray = new int [sizeNeeded];
bm.getPixels (cachedRenderArray, 0, w, 0, 0, w, h);
bm.recycle();
return cachedRenderArray;
}
private int[] cachedRenderArray = new int [256];
//==============================================================================
public static class HTTPStream
{
public HTTPStream (HttpURLConnection connection_) throws IOException
{
connection = connection_;
inputStream = new BufferedInputStream (connection.getInputStream());
}
public final void release()
{
try
{
inputStream.close();
}
catch (IOException e)
{}
connection.disconnect();
}
public final int read (byte[] buffer, int numBytes)
{
int num = 0;
try
{
num = inputStream.read (buffer, 0, numBytes);
}
catch (IOException e)
{}
if (num > 0)
position += num;
return num;
}
public final long getPosition() { return position; }
public final long getTotalLength() { return -1; }
public final boolean isExhausted() { return false; }
public final boolean setPosition (long newPos) { return false; }
private HttpURLConnection connection;
private InputStream inputStream;
private long position;
}
public static final HTTPStream createHTTPStream (String address, boolean isPost, byte[] postData,
String headers, int timeOutMs,
java.lang.StringBuffer responseHeaders)
{
try
{
HttpURLConnection connection = (HttpURLConnection) (new URL (address).openConnection());
if (connection != null)
{
try
{
if (isPost)
{
connection.setConnectTimeout (timeOutMs);
connection.setDoOutput (true);
connection.setChunkedStreamingMode (0);
OutputStream out = connection.getOutputStream();
out.write (postData);
out.flush();
}
return new HTTPStream (connection);
}
catch (Throwable e)
{
connection.disconnect();
}
}
}
catch (Throwable e)
{}
return null;
}
public final void launchURL (String url)
{
startActivity (new Intent (Intent.ACTION_VIEW, Uri.parse (url)));
}
public static final String getLocaleValue (boolean isRegion)
{
java.util.Locale locale = java.util.Locale.getDefault();
return isRegion ? locale.getDisplayCountry (java.util.Locale.US)
: locale.getDisplayLanguage (java.util.Locale.US);
}
//==============================================================================
private final class SingleMediaScanner implements MediaScannerConnectionClient
{
public SingleMediaScanner (Context context, String filename)
{
file = filename;
msc = new MediaScannerConnection (context, this);
msc.connect();
}
@Override
public void onMediaScannerConnected()
{
msc.scanFile (file, null);
}
@Override
public void onScanCompleted (String path, Uri uri)
{
msc.disconnect();
}
private MediaScannerConnection msc;
private String file;
}
public final void scanFile (String filename)
{
new SingleMediaScanner (this, filename);
}
}

View File

@@ -24,35 +24,6 @@
namespace beast
{
void MACAddress::findAllAddresses (Array<MACAddress>& result)
{
const int s = socket (AF_INET, SOCK_DGRAM, 0);
if (s != -1)
{
char buf [1024];
struct ifconf ifc;
ifc.ifc_len = sizeof (buf);
ifc.ifc_buf = buf;
ioctl (s, SIOCGIFCONF, &ifc);
for (unsigned int i = 0; i < ifc.ifc_len / sizeof (struct ifreq); ++i)
{
struct ifreq ifr;
strcpy (ifr.ifr_name, ifc.ifc_req[i].ifr_name);
if (ioctl (s, SIOCGIFFLAGS, &ifr) == 0
&& (ifr.ifr_flags & IFF_LOOPBACK) == 0
&& ioctl (s, SIOCGIFHWADDR, &ifr) == 0)
{
result.addIfNotAlreadyThere (MACAddress ((const uint8*) ifr.ifr_hwaddr.sa_data));
}
}
close (s);
}
}
bool Process::openEmailWithAttachments (const String& /* targetEmailAddress */,
const String& /* emailSubject */,
const String& /* bodyText */,

View File

@@ -24,33 +24,6 @@
namespace beast
{
void MACAddress::findAllAddresses (Array<MACAddress>& result)
{
ifaddrs* addrs = nullptr;
if (getifaddrs (&addrs) == 0)
{
for (const ifaddrs* cursor = addrs; cursor != nullptr; cursor = cursor->ifa_next)
{
sockaddr_storage* sto = (sockaddr_storage*) cursor->ifa_addr;
if (sto->ss_family == AF_LINK)
{
const sockaddr_dl* const sadd = (const sockaddr_dl*) cursor->ifa_addr;
#ifndef IFT_ETHER
#define IFT_ETHER 6
#endif
if (sadd->sdl_type == IFT_ETHER)
result.addIfNotAlreadyThere (MACAddress (((const uint8*) sadd->sdl_data) + sadd->sdl_nlen));
}
}
freeifaddrs (addrs);
}
}
//==============================================================================
bool Process::openEmailWithAttachments (const String& targetEmailAddress,
const String& emailSubject,
const String& bodyText,

View File

@@ -1,34 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace beast
{
//#pragma message(BEAST_FILEANDLINE_ "Missing platform-specific implementation")
FPUFlags FPUFlags::getCurrent ()
{
return FPUFlags ();
}
void FPUFlags::setCurrent (const FPUFlags& flags)
{
}
} // namespace beast

View File

@@ -598,48 +598,6 @@ String SystemStats::getEnvironmentVariable (const String& name, const String& de
return defaultValue;
}
//==============================================================================
void MemoryMappedFile::openInternal (const File& file, AccessMode mode)
{
bassert (mode == readOnly || mode == readWrite);
if (range.getStart() > 0)
{
const long pageSize = sysconf (_SC_PAGE_SIZE);
range.setStart (range.getStart() - (range.getStart() % pageSize));
}
fileHandle = open (file.getFullPathName().toUTF8(),
mode == readWrite ? (O_CREAT + O_RDWR) : O_RDONLY, 00644);
if (fileHandle != -1)
{
void* m = mmap (0, (size_t) range.getLength(),
mode == readWrite ? (PROT_READ | PROT_WRITE) : PROT_READ,
MAP_SHARED, fileHandle,
(off_t) range.getStart());
if (m != MAP_FAILED)
{
address = m;
madvise (m, (size_t) range.getLength(), MADV_SEQUENTIAL);
}
else
{
range = Range<int64>();
}
}
}
MemoryMappedFile::~MemoryMappedFile()
{
if (address != nullptr)
munmap (address, (size_t) range.getLength());
if (fileHandle != 0)
close (fileHandle);
}
//==============================================================================
#if BEAST_PROBEASTR_LIVE_BUILD
extern "C" const char* beast_getCurrentExecutablePath();

View File

@@ -1,181 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace beast
{
FPUFlags FPUFlags::getCurrent ()
{
unsigned int currentControl;
const unsigned int newControl = 0;
const unsigned int mask = 0;
errno_t result = _controlfp_s (&currentControl, newControl, mask);
if (result != 0)
Throw (std::runtime_error ("error in _controlfp_s"));
FPUFlags flags;
flags.setMaskNaNs ((currentControl & _EM_INVALID) == _EM_INVALID);
flags.setMaskDenormals ((currentControl & _EM_DENORMAL) == _EM_DENORMAL);
flags.setMaskZeroDivides ((currentControl & _EM_ZERODIVIDE) == _EM_ZERODIVIDE);
flags.setMaskOverflows ((currentControl & _EM_OVERFLOW) == _EM_OVERFLOW);
flags.setMaskUnderflows ((currentControl & _EM_UNDERFLOW) == _EM_UNDERFLOW);
//flags.setMaskInexacts ((currentControl & _EM_INEXACT) == _EM_INEXACT);
flags.setFlushDenormals ((currentControl & _DN_FLUSH) == _DN_FLUSH);
flags.setInfinitySigned ((currentControl & _IC_AFFINE) == _IC_AFFINE);
Rounding rounding = roundDown;
switch (currentControl & _MCW_RC)
{
case _RC_CHOP:
rounding = roundChop;
break;
case _RC_UP:
rounding = roundUp;
break;
case _RC_DOWN:
rounding = roundDown;
break;
case _RC_NEAR:
rounding = roundNear;
break;
default:
Throw (std::runtime_error ("unknown rounding in _controlfp_s"));
};
flags.setRounding (rounding);
Precision precision = bits64;
switch (currentControl & _MCW_PC )
{
case _PC_64:
precision = bits64;
break;
case _PC_53:
precision = bits53;
break;
case _PC_24:
precision = bits24;
break;
default:
Throw (std::runtime_error ("unknown precision in _controlfp_s"));
};
flags.setPrecision (precision);
return flags;
}
static void setControl (const FPUFlags::Flag& flag,
unsigned int& newControl,
unsigned int& mask,
unsigned int constant)
{
if (flag.is_set ())
{
mask |= constant;
if (flag.value ())
newControl |= constant;
}
}
void FPUFlags::setCurrent (const FPUFlags& flags)
{
unsigned int newControl = 0;
unsigned int mask = 0;
setControl (flags.getMaskNaNs (), newControl, mask, _EM_INVALID);
setControl (flags.getMaskDenormals (), newControl, mask, _EM_DENORMAL);
setControl (flags.getMaskZeroDivides (), newControl, mask, _EM_ZERODIVIDE);
setControl (flags.getMaskOverflows (), newControl, mask, _EM_OVERFLOW);
setControl (flags.getMaskUnderflows (), newControl, mask, _EM_UNDERFLOW);
//setControl (flags.getMaskInexacts(), newControl, mask, _EM_INEXACT);
setControl (flags.getFlushDenormals (), newControl, mask, _DN_FLUSH);
setControl (flags.getInfinitySigned (), newControl, mask, _IC_AFFINE);
if (flags.getRounding ().is_set ())
{
Rounding rounding = flags.getRounding ().value ();
switch (rounding)
{
case roundChop:
mask |= _MCW_RC;
newControl |= _RC_CHOP;
break;
case roundUp:
mask |= _MCW_RC;
newControl |= _RC_UP;
break;
case roundDown:
mask |= _MCW_RC;
newControl |= _RC_DOWN;
break;
case roundNear:
mask |= _MCW_RC;
newControl |= _RC_NEAR;
break;
}
}
if (flags.getPrecision ().is_set ())
{
switch (flags.getPrecision ().value ())
{
case bits64:
mask |= _MCW_PC;
newControl |= _PC_64;
break;
case bits53:
mask |= _MCW_PC;
newControl |= _PC_53;
break;
case bits24:
mask |= _MCW_PC;
newControl |= _PC_24;
break;
}
}
unsigned int currentControl;
errno_t result = _controlfp_s (&currentControl, newControl, mask);
if (result != 0)
Throw (std::runtime_error ("error in _controlfp_s"));
}
} // namespace beast

View File

@@ -466,63 +466,8 @@ Result RandomAccessFile::nativeFlush ()
return result;
}
//==============================================================================
void MemoryMappedFile::openInternal (const File& file, AccessMode mode)
{
bassert (mode == readOnly || mode == readWrite);
if (range.getStart() > 0)
{
SYSTEM_INFO systemInfo;
GetNativeSystemInfo (&systemInfo);
range.setStart (range.getStart() - (range.getStart() % systemInfo.dwAllocationGranularity));
}
DWORD accessMode = GENERIC_READ, createType = OPEN_EXISTING;
DWORD protect = PAGE_READONLY, access = FILE_MAP_READ;
if (mode == readWrite)
{
accessMode = GENERIC_READ | GENERIC_WRITE;
createType = OPEN_ALWAYS;
protect = PAGE_READWRITE;
access = FILE_MAP_ALL_ACCESS;
}
HANDLE h = CreateFile (file.getFullPathName().toWideCharPointer(), accessMode, FILE_SHARE_READ, 0,
createType, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, 0);
if (h != INVALID_HANDLE_VALUE)
{
fileHandle = (void*) h;
HANDLE mappingHandle = CreateFileMapping (h, 0, protect, (DWORD) (range.getEnd() >> 32), (DWORD) range.getEnd(), 0);
if (mappingHandle != 0)
{
address = MapViewOfFile (mappingHandle, access, (DWORD) (range.getStart() >> 32),
(DWORD) range.getStart(), (SIZE_T) range.getLength());
if (address == nullptr)
range = Range<int64>();
CloseHandle (mappingHandle);
}
}
}
MemoryMappedFile::~MemoryMappedFile()
{
if (address != nullptr)
UnmapViewOfFile (address);
if (fileHandle != nullptr)
CloseHandle ((HANDLE) fileHandle);
}
//==============================================================================
int64 File::getSize() const
{
WIN32_FILE_ATTRIBUTE_DATA attributes;

View File

@@ -24,98 +24,6 @@
namespace beast
{
struct GetAdaptersInfoHelper
{
bool callGetAdaptersInfo()
{
DynamicLibrary dll ("iphlpapi.dll");
BEAST_LOAD_WINAPI_FUNCTION (dll, GetAdaptersInfo, getAdaptersInfo, DWORD, (PIP_ADAPTER_INFO, PULONG))
if (getAdaptersInfo == nullptr)
return false;
adapterInfo.malloc (1);
ULONG len = sizeof (IP_ADAPTER_INFO);
if (getAdaptersInfo (adapterInfo, &len) == ERROR_BUFFER_OVERFLOW)
adapterInfo.malloc (len, 1);
return getAdaptersInfo (adapterInfo, &len) == NO_ERROR;
}
HeapBlock<IP_ADAPTER_INFO> adapterInfo;
};
namespace MACAddressHelpers
{
void getViaGetAdaptersInfo (Array<MACAddress>& result)
{
GetAdaptersInfoHelper gah;
if (gah.callGetAdaptersInfo())
{
for (PIP_ADAPTER_INFO adapter = gah.adapterInfo; adapter != nullptr; adapter = adapter->Next)
if (adapter->AddressLength >= 6)
result.addIfNotAlreadyThere (MACAddress (adapter->Address));
}
}
void getViaNetBios (Array<MACAddress>& result)
{
DynamicLibrary dll ("netapi32.dll");
BEAST_LOAD_WINAPI_FUNCTION (dll, Netbios, NetbiosCall, UCHAR, (PNCB))
if (NetbiosCall != 0)
{
LANA_ENUM enums = { 0 };
{
NCB ncb = { 0 };
ncb.ncb_command = NCBENUM;
ncb.ncb_buffer = (unsigned char*) &enums;
ncb.ncb_length = sizeof (LANA_ENUM);
NetbiosCall (&ncb);
}
for (int i = 0; i < enums.length; ++i)
{
NCB ncb2 = { 0 };
ncb2.ncb_command = NCBRESET;
ncb2.ncb_lana_num = enums.lana[i];
if (NetbiosCall (&ncb2) == 0)
{
NCB ncb = { 0 };
memcpy (ncb.ncb_callname, "* ", NCBNAMSZ);
ncb.ncb_command = NCBASTAT;
ncb.ncb_lana_num = enums.lana[i];
struct ASTAT
{
ADAPTER_STATUS adapt;
NAME_BUFFER NameBuff [30];
};
ASTAT astat;
zerostruct (astat);
ncb.ncb_buffer = (unsigned char*) &astat;
ncb.ncb_length = sizeof (ASTAT);
if (NetbiosCall (&ncb) == 0 && astat.adapt.adapter_type == 0xfe)
result.addIfNotAlreadyThere (MACAddress (astat.adapt.adapter_address));
}
}
}
}
}
void MACAddress::findAllAddresses (Array<MACAddress>& result)
{
MACAddressHelpers::getViaGetAdaptersInfo (result);
MACAddressHelpers::getViaNetBios (result);
}
//==============================================================================
bool Process::openEmailWithAttachments (const String& targetEmailAddress,
const String& emailSubject,
const String& bodyText,

View File

@@ -1,78 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace beast
{
MACAddress::MACAddress()
{
zeromem (address, sizeof (address));
}
MACAddress::MACAddress (const MACAddress& other)
{
memcpy (address, other.address, sizeof (address));
}
MACAddress& MACAddress::operator= (const MACAddress& other)
{
memcpy (address, other.address, sizeof (address));
return *this;
}
MACAddress::MACAddress (const uint8 bytes[6])
{
memcpy (address, bytes, sizeof (address));
}
String MACAddress::toString() const
{
String s;
for (size_t i = 0; i < sizeof (address); ++i)
{
s << String::toHexString ((int) address[i]).paddedLeft ('0', 2);
if (i < sizeof (address) - 1)
s << '-';
}
return s;
}
int64 MACAddress::toInt64() const noexcept
{
int64 n = 0;
for (int i = (int) sizeof (address); --i >= 0;)
n = (n << 8) | address[i];
return n;
}
bool MACAddress::isNull() const noexcept { return toInt64() == 0; }
bool MACAddress::operator== (const MACAddress& other) const noexcept { return memcmp (address, other.address, sizeof (address)) == 0; }
bool MACAddress::operator!= (const MACAddress& other) const noexcept { return ! operator== (other); }
} // namespace beast

View File

@@ -1,85 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_MACADDRESS_H_INCLUDED
#define BEAST_MACADDRESS_H_INCLUDED
namespace beast
{
//==============================================================================
/**
A wrapper for a streaming (TCP) socket.
This allows low-level use of sockets; for an easier-to-use messaging layer on top of
sockets, you could also try the InterprocessConnection class.
@see DatagramSocket, InterprocessConnection, InterprocessConnectionServer
*/
class BEAST_API MACAddress
{
public:
//==============================================================================
/** Populates a list of the MAC addresses of all the available network cards. */
static void findAllAddresses (Array<MACAddress>& results);
//==============================================================================
/** Creates a null address (00-00-00-00-00-00). */
MACAddress();
/** Creates a copy of another address. */
MACAddress (const MACAddress& other);
/** Creates a copy of another address. */
MACAddress& operator= (const MACAddress& other);
/** Creates an address from 6 bytes. */
explicit MACAddress (const uint8 bytes[6]);
/** Returns a pointer to the 6 bytes that make up this address. */
const uint8* getBytes() const noexcept { return address; }
/** Returns a dash-separated string in the form "11-22-33-44-55-66" */
String toString() const;
/** Returns the address in the lower 6 bytes of an int64.
This uses a little-endian arrangement, with the first byte of the address being
stored in the least-significant byte of the result value.
*/
int64 toInt64() const noexcept;
/** Returns true if this address is null (00-00-00-00-00-00). */
bool isNull() const noexcept;
bool operator== (const MACAddress& other) const noexcept;
bool operator!= (const MACAddress& other) const noexcept;
//==============================================================================
private:
uint8 address[6];
};
} // namespace beast
#endif // BEAST_MACADDRESS_H_INCLUDED

View File

@@ -1,66 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace beast
{
NamedPipe::NamedPipe()
{
}
NamedPipe::~NamedPipe()
{
close();
}
bool NamedPipe::openExisting (const String& pipeName)
{
close();
ScopedWriteLock sl (lock);
currentPipeName = pipeName;
return openInternal (pipeName, false);
}
bool NamedPipe::isOpen() const
{
return pimpl != nullptr;
}
bool NamedPipe::createNewPipe (const String& pipeName)
{
close();
ScopedWriteLock sl (lock);
currentPipeName = pipeName;
return openInternal (pipeName, true);
}
String NamedPipe::getName() const
{
return currentPipeName;
}
// other methods for this class are implemented in the platform-specific files
} // namespace beast

View File

@@ -1,100 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_NAMEDPIPE_H_INCLUDED
#define BEAST_NAMEDPIPE_H_INCLUDED
namespace beast
{
//==============================================================================
/**
A cross-process pipe that can have data written to and read from it.
Two processes can use NamedPipe objects to exchange blocks of data.
@see InterprocessConnection
*/
class BEAST_API NamedPipe : LeakChecked <NamedPipe>, public Uncopyable
{
public:
//==============================================================================
/** Creates a NamedPipe. */
NamedPipe();
/** Destructor. */
~NamedPipe();
//==============================================================================
/** Tries to open a pipe that already exists.
Returns true if it succeeds.
*/
bool openExisting (const String& pipeName);
/** Tries to create a new pipe.
Returns true if it succeeds.
*/
bool createNewPipe (const String& pipeName);
/** Closes the pipe, if it's open. */
void close();
/** True if the pipe is currently open. */
bool isOpen() const;
/** Returns the last name that was used to try to open this pipe. */
String getName() const;
//==============================================================================
/** Reads data from the pipe.
This will block until another thread has written enough data into the pipe to fill
the number of bytes specified, or until another thread calls the cancelPendingReads()
method.
If the operation fails, it returns -1, otherwise, it will return the number of
bytes read.
If timeOutMilliseconds is less than zero, it will wait indefinitely, otherwise
this is a maximum timeout for reading from the pipe.
*/
int read (void* destBuffer, int maxBytesToRead, int timeOutMilliseconds);
/** Writes some data to the pipe.
@returns the number of bytes written, or -1 on failure.
*/
int write (const void* sourceBuffer, int numBytesToWrite, int timeOutMilliseconds);
private:
//==============================================================================
BEAST_PUBLIC_IN_DLL_BUILD (class Pimpl)
ScopedPointer<Pimpl> pimpl;
String currentPipeName;
ReadWriteLock lock;
bool openInternal (const String& pipeName, const bool createPipe);
};
} // namespace beast
#endif // BEAST_NAMEDPIPE_H_INCLUDED

View File

@@ -1,590 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace beast
{
#if BEAST_MSVC
#pragma warning (push)
#pragma warning (disable : 4127 4389 4018)
#endif
#ifndef AI_NUMERICSERV // (missing in older Mac SDKs)
#define AI_NUMERICSERV 0x1000
#endif
#if BEAST_WINDOWS
typedef int beast_socklen_t;
typedef SOCKET SocketHandle;
#else
typedef socklen_t beast_socklen_t;
typedef int SocketHandle;
#endif
//==============================================================================
namespace SocketHelpers
{
static void initSockets()
{
#if BEAST_WINDOWS
static bool socketsStarted = false;
if (! socketsStarted)
{
socketsStarted = true;
WSADATA wsaData;
const WORD wVersionRequested = MAKEWORD (1, 1);
WSAStartup (wVersionRequested, &wsaData);
}
#endif
}
static bool resetSocketOptions (const SocketHandle handle, const bool isDatagram, const bool allowBroadcast) noexcept
{
const int sndBufSize = 65536;
const int rcvBufSize = 65536;
const int one = 1;
return handle > 0
&& setsockopt (handle, SOL_SOCKET, SO_RCVBUF, (const char*) &rcvBufSize, sizeof (rcvBufSize)) == 0
&& setsockopt (handle, SOL_SOCKET, SO_SNDBUF, (const char*) &sndBufSize, sizeof (sndBufSize)) == 0
&& (isDatagram ? ((! allowBroadcast) || setsockopt (handle, SOL_SOCKET, SO_BROADCAST, (const char*) &one, sizeof (one)) == 0)
: (setsockopt (handle, IPPROTO_TCP, TCP_NODELAY, (const char*) &one, sizeof (one)) == 0));
}
static bool bindSocketToPort (const SocketHandle handle, const int port) noexcept
{
if (handle <= 0 || port <= 0)
return false;
struct sockaddr_in servTmpAddr;
zerostruct (servTmpAddr); // (can't use "= { 0 }" on this object because it's typedef'ed as a C struct)
servTmpAddr.sin_family = PF_INET;
servTmpAddr.sin_addr.s_addr = htonl (INADDR_ANY);
servTmpAddr.sin_port = htons ((uint16) port);
return ::bind (handle, (struct sockaddr*) &servTmpAddr, sizeof (struct sockaddr_in)) >= 0;
}
static int readSocket (const SocketHandle handle,
void* const destBuffer, const int maxBytesToRead,
bool volatile& connected,
const bool blockUntilSpecifiedAmountHasArrived) noexcept
{
int bytesRead = 0;
while (bytesRead < maxBytesToRead)
{
int bytesThisTime;
#if BEAST_WINDOWS
bytesThisTime = recv (handle, static_cast<char*> (destBuffer) + bytesRead, maxBytesToRead - bytesRead, 0);
#else
while ((bytesThisTime = (int) ::read (handle, addBytesToPointer (destBuffer, bytesRead), (size_t) (maxBytesToRead - bytesRead))) < 0
&& errno == EINTR
&& connected)
{
}
#endif
if (bytesThisTime <= 0 || ! connected)
{
if (bytesRead == 0)
bytesRead = -1;
break;
}
bytesRead += bytesThisTime;
if (! blockUntilSpecifiedAmountHasArrived)
break;
}
return bytesRead;
}
static int waitForReadiness (const SocketHandle handle, const bool forReading, const int timeoutMsecs) noexcept
{
struct timeval timeout;
struct timeval* timeoutp;
if (timeoutMsecs >= 0)
{
timeout.tv_sec = timeoutMsecs / 1000;
timeout.tv_usec = (timeoutMsecs % 1000) * 1000;
timeoutp = &timeout;
}
else
{
timeoutp = 0;
}
fd_set rset, wset;
FD_ZERO (&rset);
FD_SET (handle, &rset);
FD_ZERO (&wset);
FD_SET (handle, &wset);
fd_set* const prset = forReading ? &rset : nullptr;
fd_set* const pwset = forReading ? nullptr : &wset;
#if BEAST_WINDOWS
if (select ((int) handle + 1, prset, pwset, 0, timeoutp) < 0)
return -1;
#else
{
int result;
while ((result = select (handle + 1, prset, pwset, 0, timeoutp)) < 0
&& errno == EINTR)
{
}
if (result < 0)
return -1;
}
#endif
{
int opt;
beast_socklen_t len = sizeof (opt);
if (getsockopt (handle, SOL_SOCKET, SO_ERROR, (char*) &opt, &len) < 0
|| opt != 0)
return -1;
}
return FD_ISSET (handle, forReading ? &rset : &wset) ? 1 : 0;
}
static bool setSocketBlockingState (const SocketHandle handle, const bool shouldBlock) noexcept
{
#if BEAST_WINDOWS
u_long nonBlocking = shouldBlock ? 0 : (u_long) 1;
return ioctlsocket (handle, FIONBIO, &nonBlocking) == 0;
#else
int socketFlags = fcntl (handle, F_GETFL, 0);
if (socketFlags == -1)
return false;
if (shouldBlock)
socketFlags &= ~O_NONBLOCK;
else
socketFlags |= O_NONBLOCK;
return fcntl (handle, F_SETFL, socketFlags) == 0;
#endif
}
static bool connectSocket (int volatile& handle,
const bool isDatagram,
struct addrinfo** const serverAddress,
const String& hostName,
const int portNumber,
const int timeOutMillisecs) noexcept
{
struct addrinfo hints;
zerostruct (hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = isDatagram ? SOCK_DGRAM : SOCK_STREAM;
hints.ai_flags = AI_NUMERICSERV;
struct addrinfo* info = nullptr;
if (getaddrinfo (hostName.toUTF8(), String (portNumber).toUTF8(), &hints, &info) != 0
|| info == nullptr)
return false;
if (handle < 0)
handle = (int) socket (info->ai_family, info->ai_socktype, 0);
if (handle < 0)
{
freeaddrinfo (info);
return false;
}
if (isDatagram)
{
if (*serverAddress != nullptr)
freeaddrinfo (*serverAddress);
*serverAddress = info;
return true;
}
setSocketBlockingState (handle, false);
const int result = ::connect (handle, info->ai_addr, (socklen_t) info->ai_addrlen);
freeaddrinfo (info);
if (result < 0)
{
#if BEAST_WINDOWS
if (result == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK)
#else
if (errno == EINPROGRESS)
#endif
{
if (waitForReadiness (handle, false, timeOutMillisecs) != 1)
{
setSocketBlockingState (handle, true);
return false;
}
}
}
setSocketBlockingState (handle, true);
resetSocketOptions (handle, false, false);
return true;
}
}
//==============================================================================
StreamingSocket::StreamingSocket()
: portNumber (0),
handle (-1),
connected (false),
isListener (false)
{
SocketHelpers::initSockets();
}
StreamingSocket::StreamingSocket (const String& hostName_,
const int portNumber_,
const int handle_)
: hostName (hostName_),
portNumber (portNumber_),
handle (handle_),
connected (true),
isListener (false)
{
SocketHelpers::initSockets();
SocketHelpers::resetSocketOptions (handle_, false, false);
}
StreamingSocket::~StreamingSocket()
{
close();
}
//==============================================================================
int StreamingSocket::read (void* destBuffer, const int maxBytesToRead, const bool blockUntilSpecifiedAmountHasArrived)
{
return (connected && ! isListener) ? SocketHelpers::readSocket (handle, destBuffer, maxBytesToRead, connected, blockUntilSpecifiedAmountHasArrived)
: -1;
}
int StreamingSocket::write (const void* sourceBuffer, const int numBytesToWrite)
{
if (isListener || ! connected)
return -1;
#if BEAST_WINDOWS
return send (handle, (const char*) sourceBuffer, numBytesToWrite, 0);
#else
int result;
while ((result = (int) ::write (handle, sourceBuffer, (size_t) numBytesToWrite)) < 0
&& errno == EINTR)
{
}
return result;
#endif
}
//==============================================================================
int StreamingSocket::waitUntilReady (const bool readyForReading,
const int timeoutMsecs) const
{
return connected ? SocketHelpers::waitForReadiness (handle, readyForReading, timeoutMsecs)
: -1;
}
//==============================================================================
bool StreamingSocket::bindToPort (const int port)
{
return SocketHelpers::bindSocketToPort (handle, port);
}
bool StreamingSocket::connect (const String& remoteHostName,
const int remotePortNumber,
const int timeOutMillisecs)
{
if (isListener)
{
bassertfalse; // a listener socket can't connect to another one!
return false;
}
if (connected)
close();
hostName = remoteHostName;
portNumber = remotePortNumber;
isListener = false;
connected = SocketHelpers::connectSocket (handle, false, nullptr, remoteHostName,
remotePortNumber, timeOutMillisecs);
if (! (connected && SocketHelpers::resetSocketOptions (handle, false, false)))
{
close();
return false;
}
return true;
}
void StreamingSocket::close()
{
#if BEAST_WINDOWS
if (handle != SOCKET_ERROR || connected)
closesocket (handle);
connected = false;
#else
if (connected)
{
connected = false;
if (isListener)
{
// need to do this to interrupt the accept() function..
StreamingSocket temp;
temp.connect ("localhost", portNumber, 1000);
}
}
if (handle != -1)
::close (handle);
#endif
hostName = String::empty;
portNumber = 0;
handle = -1;
isListener = false;
}
//==============================================================================
bool StreamingSocket::createListener (const int newPortNumber, const String& localHostName)
{
if (connected)
close();
hostName = "listener";
portNumber = newPortNumber;
isListener = true;
struct sockaddr_in servTmpAddr;
zerostruct (servTmpAddr);
servTmpAddr.sin_family = PF_INET;
servTmpAddr.sin_addr.s_addr = htonl (INADDR_ANY);
if (localHostName.isNotEmpty())
servTmpAddr.sin_addr.s_addr = ::inet_addr (localHostName.toUTF8());
servTmpAddr.sin_port = htons ((uint16) portNumber);
handle = (int) socket (AF_INET, SOCK_STREAM, 0);
if (handle < 0)
return false;
const int reuse = 1;
setsockopt (handle, SOL_SOCKET, SO_REUSEADDR, (const char*) &reuse, sizeof (reuse));
if (::bind (handle, (struct sockaddr*) &servTmpAddr, sizeof (struct sockaddr_in)) < 0
|| listen (handle, SOMAXCONN) < 0)
{
close();
return false;
}
connected = true;
return true;
}
StreamingSocket* StreamingSocket::waitForNextConnection() const
{
bassert (isListener || ! connected); // to call this method, you first have to use createListener() to
// prepare this socket as a listener.
if (connected && isListener)
{
struct sockaddr_storage address;
beast_socklen_t len = sizeof (address);
const int newSocket = (int) accept (handle, (struct sockaddr*) &address, &len);
if (newSocket >= 0 && connected)
return new StreamingSocket (inet_ntoa (((struct sockaddr_in*) &address)->sin_addr),
portNumber, newSocket);
}
return nullptr;
}
bool StreamingSocket::isLocal() const noexcept
{
return hostName == "127.0.0.1";
}
//==============================================================================
//==============================================================================
DatagramSocket::DatagramSocket (const int localPortNumber, const bool allowBroadcast_)
: portNumber (0),
handle (-1),
connected (true),
allowBroadcast (allowBroadcast_),
serverAddress (nullptr)
{
SocketHelpers::initSockets();
handle = (int) socket (AF_INET, SOCK_DGRAM, 0);
bindToPort (localPortNumber);
}
DatagramSocket::DatagramSocket (const String& hostName_, const int portNumber_,
const int handle_, const int localPortNumber)
: hostName (hostName_),
portNumber (portNumber_),
handle (handle_),
connected (true),
allowBroadcast (false),
serverAddress (nullptr)
{
SocketHelpers::initSockets();
SocketHelpers::resetSocketOptions (handle_, true, allowBroadcast);
bindToPort (localPortNumber);
}
DatagramSocket::~DatagramSocket()
{
close();
if (serverAddress != nullptr)
freeaddrinfo (static_cast <struct addrinfo*> (serverAddress));
}
void DatagramSocket::close()
{
#if BEAST_WINDOWS
closesocket (handle);
connected = false;
#else
connected = false;
::close (handle);
#endif
hostName = String::empty;
portNumber = 0;
handle = -1;
}
bool DatagramSocket::bindToPort (const int port)
{
return SocketHelpers::bindSocketToPort (handle, port);
}
bool DatagramSocket::connect (const String& remoteHostName,
const int remotePortNumber,
const int timeOutMillisecs)
{
if (connected)
close();
hostName = remoteHostName;
portNumber = remotePortNumber;
connected = SocketHelpers::connectSocket (handle, true, (struct addrinfo**) &serverAddress,
remoteHostName, remotePortNumber,
timeOutMillisecs);
if (! (connected && SocketHelpers::resetSocketOptions (handle, true, allowBroadcast)))
{
close();
return false;
}
return true;
}
DatagramSocket* DatagramSocket::waitForNextConnection() const
{
while (waitUntilReady (true, -1) == 1)
{
struct sockaddr_storage address;
beast_socklen_t len = sizeof (address);
char buf[1];
if (recvfrom (handle, buf, 0, 0, (struct sockaddr*) &address, &len) > 0)
return new DatagramSocket (inet_ntoa (((struct sockaddr_in*) &address)->sin_addr),
ntohs (((struct sockaddr_in*) &address)->sin_port),
-1, -1);
}
return nullptr;
}
//==============================================================================
int DatagramSocket::waitUntilReady (const bool readyForReading,
const int timeoutMsecs) const
{
return connected ? SocketHelpers::waitForReadiness (handle, readyForReading, timeoutMsecs)
: -1;
}
int DatagramSocket::read (void* destBuffer, const int maxBytesToRead, const bool blockUntilSpecifiedAmountHasArrived)
{
return connected ? SocketHelpers::readSocket (handle, destBuffer, maxBytesToRead, connected, blockUntilSpecifiedAmountHasArrived)
: -1;
}
int DatagramSocket::write (const void* sourceBuffer, const int numBytesToWrite)
{
// You need to call connect() first to set the server address..
bassert (serverAddress != nullptr && connected);
return connected ? (int) sendto (handle, (const char*) sourceBuffer,
(size_t) numBytesToWrite, 0,
static_cast <const struct addrinfo*> (serverAddress)->ai_addr,
(beast_socklen_t) static_cast <const struct addrinfo*> (serverAddress)->ai_addrlen)
: -1;
}
bool DatagramSocket::isLocal() const noexcept
{
return hostName == "127.0.0.1";
}
#if BEAST_MSVC
#pragma warning (pop)
#endif
} // namespace beast

View File

@@ -1,299 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_SOCKET_H_INCLUDED
#define BEAST_SOCKET_H_INCLUDED
namespace beast
{
//==============================================================================
/**
A wrapper for a streaming (TCP) socket.
This allows low-level use of sockets; for an easier-to-use messaging layer on top of
sockets, you could also try the InterprocessConnection class.
@see DatagramSocket, InterprocessConnection, InterprocessConnectionServer
*/
class BEAST_API StreamingSocket : LeakChecked <StreamingSocket>, public Uncopyable
{
public:
//==============================================================================
/** Creates an uninitialised socket.
To connect it, use the connect() method, after which you can read() or write()
to it.
To wait for other sockets to connect to this one, the createListener() method
enters "listener" mode, and can be used to spawn new sockets for each connection
that comes along.
*/
StreamingSocket();
/** Destructor. */
~StreamingSocket();
//==============================================================================
/** Binds the socket to the specified local port.
@returns true on success; false may indicate that another socket is already bound
on the same port
*/
bool bindToPort (int localPortNumber);
/** Tries to connect the socket to hostname:port.
If timeOutMillisecs is 0, then this method will block until the operating system
rejects the connection (which could take a long time).
@returns true if it succeeds.
@see isConnected
*/
bool connect (const String& remoteHostname,
int remotePortNumber,
int timeOutMillisecs = 3000);
/** True if the socket is currently connected. */
bool isConnected() const noexcept { return connected; }
/** Closes the connection. */
void close();
/** Returns the name of the currently connected host. */
const String& getHostName() const noexcept { return hostName; }
/** Returns the port number that's currently open. */
int getPort() const noexcept { return portNumber; }
/** True if the socket is connected to this machine rather than over the network. */
bool isLocal() const noexcept;
/** Returns the OS's socket handle that's currently open. */
int getRawSocketHandle() const noexcept { return handle; }
//==============================================================================
/** Waits until the socket is ready for reading or writing.
If readyForReading is true, it will wait until the socket is ready for
reading; if false, it will wait until it's ready for writing.
If the timeout is < 0, it will wait forever, or else will give up after
the specified time.
If the socket is ready on return, this returns 1. If it times-out before
the socket becomes ready, it returns 0. If an error occurs, it returns -1.
*/
int waitUntilReady (bool readyForReading,
int timeoutMsecs) const;
/** Reads bytes from the socket.
If blockUntilSpecifiedAmountHasArrived is true, the method will block until
maxBytesToRead bytes have been read, (or until an error occurs). If this
flag is false, the method will return as much data as is currently available
without blocking.
@returns the number of bytes read, or -1 if there was an error.
@see waitUntilReady
*/
int read (void* destBuffer, int maxBytesToRead,
bool blockUntilSpecifiedAmountHasArrived);
/** Writes bytes to the socket from a buffer.
Note that this method will block unless you have checked the socket is ready
for writing before calling it (see the waitUntilReady() method).
@returns the number of bytes written, or -1 if there was an error.
*/
int write (const void* sourceBuffer, int numBytesToWrite);
//==============================================================================
/** Puts this socket into "listener" mode.
When in this mode, your thread can call waitForNextConnection() repeatedly,
which will spawn new sockets for each new connection, so that these can
be handled in parallel by other threads.
@param portNumber the port number to listen on
@param localHostName the interface address to listen on - pass an empty
string to listen on all addresses
@returns true if it manages to open the socket successfully.
@see waitForNextConnection
*/
bool createListener (int portNumber, const String& localHostName = String::empty);
/** When in "listener" mode, this waits for a connection and spawns it as a new
socket.
The object that gets returned will be owned by the caller.
This method can only be called after using createListener().
@see createListener
*/
StreamingSocket* waitForNextConnection() const;
private:
//==============================================================================
String hostName;
int volatile portNumber, handle;
bool connected, isListener;
StreamingSocket (const String& hostname, int portNumber, int handle);
};
//==============================================================================
/**
A wrapper for a datagram (UDP) socket.
This allows low-level use of sockets; for an easier-to-use messaging layer on top of
sockets, you could also try the InterprocessConnection class.
@see StreamingSocket, InterprocessConnection, InterprocessConnectionServer
*/
class BEAST_API DatagramSocket : LeakChecked <DatagramSocket>, public Uncopyable
{
public:
//==============================================================================
/**
Creates an (uninitialised) datagram socket.
The localPortNumber is the port on which to bind this socket. If this value is 0,
the port number is assigned by the operating system.
To use the socket for sending, call the connect() method. This will not immediately
make a connection, but will save the destination you've provided. After this, you can
call read() or write().
If enableBroadcasting is true, the socket will be allowed to send broadcast messages
(may require extra privileges on linux)
To wait for other sockets to connect to this one, call waitForNextConnection().
*/
DatagramSocket (int localPortNumber,
bool enableBroadcasting = false);
/** Destructor. */
~DatagramSocket();
//==============================================================================
/** Binds the socket to the specified local port.
@returns true on success; false may indicate that another socket is already bound
on the same port
*/
bool bindToPort (int localPortNumber);
/** Tries to connect the socket to hostname:port.
If timeOutMillisecs is 0, then this method will block until the operating system
rejects the connection (which could take a long time).
@returns true if it succeeds.
@see isConnected
*/
bool connect (const String& remoteHostname,
int remotePortNumber,
int timeOutMillisecs = 3000);
/** True if the socket is currently connected. */
bool isConnected() const noexcept { return connected; }
/** Closes the connection. */
void close();
/** Returns the name of the currently connected host. */
const String& getHostName() const noexcept { return hostName; }
/** Returns the port number that's currently open. */
int getPort() const noexcept { return portNumber; }
/** True if the socket is connected to this machine rather than over the network. */
bool isLocal() const noexcept;
/** Returns the OS's socket handle that's currently open. */
int getRawSocketHandle() const noexcept { return handle; }
//==============================================================================
/** Waits until the socket is ready for reading or writing.
If readyForReading is true, it will wait until the socket is ready for
reading; if false, it will wait until it's ready for writing.
If the timeout is < 0, it will wait forever, or else will give up after
the specified time.
If the socket is ready on return, this returns 1. If it times-out before
the socket becomes ready, it returns 0. If an error occurs, it returns -1.
*/
int waitUntilReady (bool readyForReading,
int timeoutMsecs) const;
/** Reads bytes from the socket.
If blockUntilSpecifiedAmountHasArrived is true, the method will block until
maxBytesToRead bytes have been read, (or until an error occurs). If this
flag is false, the method will return as much data as is currently available
without blocking.
@returns the number of bytes read, or -1 if there was an error.
@see waitUntilReady
*/
int read (void* destBuffer, int maxBytesToRead,
bool blockUntilSpecifiedAmountHasArrived);
/** Writes bytes to the socket from a buffer.
Note that this method will block unless you have checked the socket is ready
for writing before calling it (see the waitUntilReady() method).
@returns the number of bytes written, or -1 if there was an error.
*/
int write (const void* sourceBuffer, int numBytesToWrite);
//==============================================================================
/** This waits for incoming data to be sent, and returns a socket that can be used
to read it.
The object that gets returned is owned by the caller, and can't be used for
sending, but can be used to read the data.
*/
DatagramSocket* waitForNextConnection() const;
private:
//==============================================================================
String hostName;
int volatile portNumber, handle;
bool connected, allowBroadcast;
void* serverAddress;
DatagramSocket (const String& hostname, int portNumber, int handle, int localPortNumber);
};
} // namespace beast
#endif // BEAST_SOCKET_H_INCLUDED

View File

@@ -1,198 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace beast
{
namespace
{
int calcBufferStreamBufferSize (int requestedSize, InputStream* const source) noexcept
{
// You need to supply a real stream when creating a BufferedInputStream
bassert (source != nullptr);
requestedSize = bmax (256, requestedSize);
const int64 sourceSize = source->getTotalLength();
if (sourceSize >= 0 && sourceSize < requestedSize)
requestedSize = bmax (32, (int) sourceSize);
return requestedSize;
}
}
//==============================================================================
BufferedInputStream::BufferedInputStream (InputStream* const sourceStream, const int bufferSize_,
const bool deleteSourceWhenDestroyed)
: source (sourceStream, deleteSourceWhenDestroyed),
bufferSize (calcBufferStreamBufferSize (bufferSize_, sourceStream)),
position (sourceStream->getPosition()),
lastReadPos (0),
bufferStart (position),
bufferOverlap (128)
{
buffer.malloc ((size_t) bufferSize);
}
BufferedInputStream::BufferedInputStream (InputStream& sourceStream, const int bufferSize_)
: source (&sourceStream, false),
bufferSize (calcBufferStreamBufferSize (bufferSize_, &sourceStream)),
position (sourceStream.getPosition()),
lastReadPos (0),
bufferStart (position),
bufferOverlap (128)
{
buffer.malloc ((size_t) bufferSize);
}
BufferedInputStream::~BufferedInputStream()
{
}
//==============================================================================
int64 BufferedInputStream::getTotalLength()
{
return source->getTotalLength();
}
int64 BufferedInputStream::getPosition()
{
return position;
}
bool BufferedInputStream::setPosition (int64 newPosition)
{
position = bmax ((int64) 0, newPosition);
return true;
}
bool BufferedInputStream::isExhausted()
{
return position >= lastReadPos && source->isExhausted();
}
void BufferedInputStream::ensureBuffered()
{
const int64 bufferEndOverlap = lastReadPos - bufferOverlap;
if (position < bufferStart || position >= bufferEndOverlap)
{
int bytesRead;
if (position < lastReadPos
&& position >= bufferEndOverlap
&& position >= bufferStart)
{
const int bytesToKeep = (int) (lastReadPos - position);
memmove (buffer, buffer + (int) (position - bufferStart), (size_t) bytesToKeep);
bufferStart = position;
bytesRead = source->read (buffer + bytesToKeep,
(int) (bufferSize - bytesToKeep));
lastReadPos += bytesRead;
bytesRead += bytesToKeep;
}
else
{
bufferStart = position;
source->setPosition (bufferStart);
bytesRead = source->read (buffer, bufferSize);
lastReadPos = bufferStart + bytesRead;
}
while (bytesRead < bufferSize)
buffer [bytesRead++] = 0;
}
}
int BufferedInputStream::read (void* destBuffer, int maxBytesToRead)
{
bassert (destBuffer != nullptr && maxBytesToRead >= 0);
if (position >= bufferStart
&& position + maxBytesToRead <= lastReadPos)
{
memcpy (destBuffer, buffer + (int) (position - bufferStart), (size_t) maxBytesToRead);
position += maxBytesToRead;
return maxBytesToRead;
}
else
{
if (position < bufferStart || position >= lastReadPos)
ensureBuffered();
int bytesRead = 0;
while (maxBytesToRead > 0)
{
const int bytesAvailable = bmin (maxBytesToRead, (int) (lastReadPos - position));
if (bytesAvailable > 0)
{
memcpy (destBuffer, buffer + (int) (position - bufferStart), (size_t) bytesAvailable);
maxBytesToRead -= bytesAvailable;
bytesRead += bytesAvailable;
position += bytesAvailable;
destBuffer = static_cast <char*> (destBuffer) + bytesAvailable;
}
const int64 oldLastReadPos = lastReadPos;
ensureBuffered();
if (oldLastReadPos == lastReadPos)
break; // if ensureBuffered() failed to read any more data, bail out
if (isExhausted())
break;
}
return bytesRead;
}
}
String BufferedInputStream::readString()
{
if (position >= bufferStart
&& position < lastReadPos)
{
const int maxChars = (int) (lastReadPos - position);
const char* const src = buffer + (int) (position - bufferStart);
for (int i = 0; i < maxChars; ++i)
{
if (src[i] == 0)
{
position += i + 1;
return String::fromUTF8 (src, i);
}
}
}
return InputStream::readString();
}
} // namespace beast

View File

@@ -1,91 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_BUFFEREDINPUTSTREAM_H_INCLUDED
#define BEAST_BUFFEREDINPUTSTREAM_H_INCLUDED
namespace beast
{
//==============================================================================
/** Wraps another input stream, and reads from it using an intermediate buffer
If you're using an input stream such as a file input stream, and making lots of
small read accesses to it, it's probably sensible to wrap it in one of these,
so that the source stream gets accessed in larger chunk sizes, meaning less
work for the underlying stream.
*/
class BEAST_API BufferedInputStream
: public InputStream
, LeakChecked <BufferedInputStream>
{
public:
//==============================================================================
/** Creates a BufferedInputStream from an input source.
@param sourceStream the source stream to read from
@param bufferSize the size of reservoir to use to buffer the source
@param deleteSourceWhenDestroyed whether the sourceStream that is passed in should be
deleted by this object when it is itself deleted.
*/
BufferedInputStream (InputStream* sourceStream,
int bufferSize,
bool deleteSourceWhenDestroyed);
/** Creates a BufferedInputStream from an input source.
@param sourceStream the source stream to read from - the source stream must not
be deleted until this object has been destroyed.
@param bufferSize the size of reservoir to use to buffer the source
*/
BufferedInputStream (InputStream& sourceStream, int bufferSize);
/** Destructor.
This may also delete the source stream, if that option was chosen when the
buffered stream was created.
*/
~BufferedInputStream();
//==============================================================================
int64 getTotalLength();
int64 getPosition();
bool setPosition (int64 newPosition);
int read (void* destBuffer, int maxBytesToRead);
String readString();
bool isExhausted();
private:
//==============================================================================
OptionalScopedPointer<InputStream> source;
int bufferSize;
int64 position, lastReadPos, bufferStart, bufferOverlap;
HeapBlock <char> buffer;
void ensureBuffered();
};
} // namespace beast
#endif // BEAST_BUFFEREDINPUTSTREAM_H_INCLUDED

View File

@@ -35,7 +35,7 @@ class MemoryBlock;
Input and output streams are used throughout the library - subclasses can override
some or all of the virtual functions to implement their behaviour.
@see OutputStream, MemoryInputStream, BufferedInputStream, FileInputStream
@see OutputStream, FileInputStream
*/
class BEAST_API InputStream
: public Uncopyable

View File

@@ -1,156 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace beast
{
MemoryInputStream::MemoryInputStream (const void* const sourceData,
const size_t sourceDataSize,
const bool keepInternalCopy)
: data (sourceData),
dataSize (sourceDataSize),
position (0)
{
if (keepInternalCopy)
createInternalCopy();
}
MemoryInputStream::MemoryInputStream (const MemoryBlock& sourceData,
const bool keepInternalCopy)
: data (sourceData.getData()),
dataSize (sourceData.getSize()),
position (0)
{
if (keepInternalCopy)
createInternalCopy();
}
void MemoryInputStream::createInternalCopy()
{
internalCopy.malloc (dataSize);
memcpy (internalCopy, data, dataSize);
data = internalCopy;
}
MemoryInputStream::~MemoryInputStream()
{
}
int64 MemoryInputStream::getTotalLength()
{
return dataSize;
}
int MemoryInputStream::read (void* const buffer, const int howMany)
{
bassert (buffer != nullptr && howMany >= 0);
const int num = bmin (howMany, (int) (dataSize - position));
if (num <= 0)
return 0;
memcpy (buffer, addBytesToPointer (data, position), (size_t) num);
position += (unsigned int) num;
return num;
}
bool MemoryInputStream::isExhausted()
{
return position >= dataSize;
}
bool MemoryInputStream::setPosition (const int64 pos)
{
position = (size_t) blimit ((int64) 0, (int64) dataSize, pos);
return true;
}
int64 MemoryInputStream::getPosition()
{
return position;
}
//==============================================================================
class MemoryStreamTests : public UnitTest
{
public:
MemoryStreamTests() : UnitTest ("MemoryStream", "beast") { }
void runTest()
{
beginTestCase ("Basics");
Random r;
int randomInt = r.nextInt();
int64 randomInt64 = r.nextInt64();
double randomDouble = r.nextDouble();
String randomString (createRandomWideCharString());
MemoryOutputStream mo;
mo.writeInt (randomInt);
mo.writeIntBigEndian (randomInt);
mo.writeCompressedInt (randomInt);
mo.writeString (randomString);
mo.writeInt64 (randomInt64);
mo.writeInt64BigEndian (randomInt64);
mo.writeDouble (randomDouble);
mo.writeDoubleBigEndian (randomDouble);
MemoryInputStream mi (mo.getData(), mo.getDataSize(), false);
expect (mi.readInt() == randomInt);
expect (mi.readIntBigEndian() == randomInt);
expect (mi.readCompressedInt() == randomInt);
expectEquals (mi.readString(), randomString);
expect (mi.readInt64() == randomInt64);
expect (mi.readInt64BigEndian() == randomInt64);
expect (mi.readDouble() == randomDouble);
expect (mi.readDoubleBigEndian() == randomDouble);
}
static String createRandomWideCharString()
{
beast_wchar buffer [50] = { 0 };
Random r;
for (int i = 0; i < numElementsInArray (buffer) - 1; ++i)
{
if (r.nextBool())
{
do
{
buffer[i] = (beast_wchar) (1 + r.nextInt (0x10ffff - 1));
}
while (! CharPointer_UTF16::canRepresent (buffer[i]));
}
else
buffer[i] = (beast_wchar) (1 + r.nextInt (0xff));
}
return CharPointer_UTF32 (buffer);
}
};
static MemoryStreamTests memoryStreamTests;
} // namespace beast

View File

@@ -1,96 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_MEMORYINPUTSTREAM_H_INCLUDED
#define BEAST_MEMORYINPUTSTREAM_H_INCLUDED
namespace beast
{
//==============================================================================
/**
Allows a block of data to be accessed as a stream.
This can either be used to refer to a shared block of memory, or can make its
own internal copy of the data when the MemoryInputStream is created.
*/
class BEAST_API MemoryInputStream
: public InputStream
, LeakChecked <MemoryInputStream>
{
public:
//==============================================================================
/** Creates a MemoryInputStream.
@param sourceData the block of data to use as the stream's source
@param sourceDataSize the number of bytes in the source data block
@param keepInternalCopyOfData if false, the stream will just keep a pointer to
the source data, so this data shouldn't be changed
for the lifetime of the stream; if this parameter is
true, the stream will make its own copy of the
data and use that.
*/
MemoryInputStream (const void* sourceData,
size_t sourceDataSize,
bool keepInternalCopyOfData = false);
/** Creates a MemoryInputStream.
@param data a block of data to use as the stream's source
@param keepInternalCopyOfData if false, the stream will just keep a reference to
the source data, so this data shouldn't be changed
for the lifetime of the stream; if this parameter is
true, the stream will make its own copy of the
data and use that.
*/
MemoryInputStream (const MemoryBlock& data,
bool keepInternalCopyOfData);
/** Destructor. */
~MemoryInputStream();
/** Returns a pointer to the source data block from which this stream is reading. */
const void* getData() const noexcept { return data; }
/** Returns the number of bytes of source data in the block from which this stream is reading. */
size_t getDataSize() const noexcept { return dataSize; }
//==============================================================================
int64 getPosition();
bool setPosition (int64 pos);
int64 getTotalLength();
bool isExhausted();
int read (void* destBuffer, int maxBytesToRead);
private:
//==============================================================================
const void* data;
size_t dataSize, position;
HeapBlock<char> internalCopy;
void createInternalCopy();
};
} // namespace beast
#endif // BEAST_MEMORYINPUTSTREAM_H_INCLUDED

View File

@@ -1,82 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace beast
{
SubregionStream::SubregionStream (InputStream* const sourceStream,
const int64 start, const int64 length,
const bool deleteSourceWhenDestroyed)
: source (sourceStream, deleteSourceWhenDestroyed),
startPositionInSourceStream (start),
lengthOfSourceStream (length)
{
SubregionStream::setPosition (0);
}
SubregionStream::~SubregionStream()
{
}
int64 SubregionStream::getTotalLength()
{
const int64 srcLen = source->getTotalLength() - startPositionInSourceStream;
return lengthOfSourceStream >= 0 ? bmin (lengthOfSourceStream, srcLen)
: srcLen;
}
int64 SubregionStream::getPosition()
{
return source->getPosition() - startPositionInSourceStream;
}
bool SubregionStream::setPosition (int64 newPosition)
{
return source->setPosition (bmax ((int64) 0, newPosition + startPositionInSourceStream));
}
int SubregionStream::read (void* destBuffer, int maxBytesToRead)
{
bassert (destBuffer != nullptr && maxBytesToRead >= 0);
if (lengthOfSourceStream < 0)
return source->read (destBuffer, maxBytesToRead);
maxBytesToRead = (int) bmin ((int64) maxBytesToRead, lengthOfSourceStream - getPosition());
if (maxBytesToRead <= 0)
return 0;
return source->read (destBuffer, maxBytesToRead);
}
bool SubregionStream::isExhausted()
{
if (lengthOfSourceStream >= 0 && getPosition() >= lengthOfSourceStream)
return true;
return source->isExhausted();
}
} // namespace beast

View File

@@ -1,88 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_SUBREGIONSTREAM_H_INCLUDED
#define BEAST_SUBREGIONSTREAM_H_INCLUDED
namespace beast
{
//==============================================================================
/** Wraps another input stream, and reads from a specific part of it.
This lets you take a subsection of a stream and present it as an entire
stream in its own right.
*/
class BEAST_API SubregionStream
: public InputStream
, LeakChecked <SubregionStream>
{
public:
//==============================================================================
/** Creates a SubregionStream from an input source.
@param sourceStream the source stream to read from
@param startPositionInSourceStream this is the position in the source stream that
corresponds to position 0 in this stream
@param lengthOfSourceStream this specifies the maximum number of bytes
from the source stream that will be passed through
by this stream. When the position of this stream
exceeds lengthOfSourceStream, it will cause an end-of-stream.
If the length passed in here is greater than the length
of the source stream (as returned by getTotalLength()),
then the smaller value will be used.
Passing a negative value for this parameter means it
will keep reading until the source's end-of-stream.
@param deleteSourceWhenDestroyed whether the sourceStream that is passed in should be
deleted by this object when it is itself deleted.
*/
SubregionStream (InputStream* sourceStream,
int64 startPositionInSourceStream,
int64 lengthOfSourceStream,
bool deleteSourceWhenDestroyed);
/** Destructor.
This may also delete the source stream, if that option was chosen when the
buffered stream was created.
*/
~SubregionStream();
//==============================================================================
int64 getTotalLength();
int64 getPosition();
bool setPosition (int64 newPosition);
int read (void* destBuffer, int maxBytesToRead);
bool isExhausted();
//==============================================================================
private:
OptionalScopedPointer<InputStream> source;
const int64 startPositionInSourceStream, lengthOfSourceStream;
};
} // namespace beast
#endif // BEAST_SUBREGIONSTREAM_H_INCLUDED

View File

@@ -1,74 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace beast
{
StringPool& Identifier::getPool()
{
static StringPool pool;
return pool;
}
Identifier::Identifier() noexcept
: name (nullptr)
{
}
Identifier::Identifier (const Identifier& other) noexcept
: name (other.name)
{
}
Identifier& Identifier::operator= (const Identifier other) noexcept
{
name = other.name;
return *this;
}
Identifier::Identifier (const String& nm)
: name (Identifier::getPool().getPooledString (nm))
{
}
Identifier::Identifier (const char* const nm)
: name (Identifier::getPool().getPooledString (nm))
{
/* An Identifier string must be suitable for use as a script variable or XML
attribute, so it can only contain this limited set of characters.. */
bassert (isValidIdentifier (toString()));
}
Identifier::~Identifier()
{
}
Identifier Identifier::null;
bool Identifier::isValidIdentifier (const String& possibleIdentifier) noexcept
{
return possibleIdentifier.isNotEmpty()
&& possibleIdentifier.containsOnly ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-:#@$%");
}
} // namespace beast

View File

@@ -1,110 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_IDENTIFIER_H_INCLUDED
#define BEAST_IDENTIFIER_H_INCLUDED
namespace beast
{
class StringPool;
//==============================================================================
/**
Represents a string identifier, designed for accessing properties by name.
Identifier objects are very light and fast to copy, but slower to initialise
from a string, so it's much faster to keep a static identifier object to refer
to frequently-used names, rather than constructing them each time you need it.
@see NamedPropertySet, ValueTree
*/
class BEAST_API Identifier
{
public:
/** Creates a null identifier. */
Identifier() noexcept;
/** Creates an identifier with a specified name.
Because this name may need to be used in contexts such as script variables or XML
tags, it must only contain ascii letters and digits, or the underscore character.
*/
Identifier (const char* name);
/** Creates an identifier with a specified name.
Because this name may need to be used in contexts such as script variables or XML
tags, it must only contain ascii letters and digits, or the underscore character.
*/
Identifier (const String& name);
/** Creates a copy of another identifier. */
Identifier (const Identifier& other) noexcept;
/** Creates a copy of another identifier. */
Identifier& operator= (const Identifier other) noexcept;
/** Destructor */
~Identifier();
/** Compares two identifiers. This is a very fast operation. */
inline bool operator== (const Identifier other) const noexcept { return name == other.name; }
/** Compares two identifiers. This is a very fast operation. */
inline bool operator!= (const Identifier other) const noexcept { return name != other.name; }
/** Returns this identifier as a string. */
String toString() const { return name; }
/** Returns this identifier's raw string pointer. */
operator const String::CharPointerType() const noexcept { return name; }
/** Returns this identifier's raw string pointer. */
const String::CharPointerType getCharPointer() const noexcept { return name; }
/** Returns true if this Identifier is not null */
bool isValid() const noexcept { return name.getAddress() != nullptr; }
/** Returns true if this Identifier is null */
bool isNull() const noexcept { return name.getAddress() == nullptr; }
/** A null identifier. */
static Identifier null;
/** Checks a given string for characters that might not be valid in an Identifier.
Since Identifiers are used as a script variables and XML attributes, they should only contain
alphanumeric characters, underscores, or the '-' and ':' characters.
*/
static bool isValidIdentifier (const String& possibleIdentifier) noexcept;
private:
//==============================================================================
String::CharPointerType name;
static StringPool& getPool();
};
} // namespace beast
#endif // BEAST_IDENTIFIER_H_INCLUDED

View File

@@ -1,173 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace beast
{
LocalisedStrings::LocalisedStrings (const String& fileContents, bool ignoreCase)
{
loadFromText (fileContents, ignoreCase);
}
LocalisedStrings::LocalisedStrings (const File& fileToLoad, bool ignoreCase)
{
loadFromText (fileToLoad.loadFileAsString(), ignoreCase);
}
LocalisedStrings::~LocalisedStrings()
{
}
//==============================================================================
String LocalisedStrings::translate (const String& text) const
{
return translations.getValue (text, text);
}
String LocalisedStrings::translate (const String& text, const String& resultIfNotFound) const
{
return translations.getValue (text, resultIfNotFound);
}
namespace
{
#if BEAST_CHECK_MEMORY_LEAKS
// By using this object to force a LocalisedStrings object to be created
// before the currentMappings object, we can force the static order-of-destruction to
// delete the currentMappings object first, which avoids a bogus leak warning.
// (Oddly, just creating a LocalisedStrings on the stack doesn't work in gcc, it
// has to be created with 'new' for this to work..)
struct LeakAvoidanceTrick
{
LeakAvoidanceTrick()
{
const ScopedPointer<LocalisedStrings> dummy (new LocalisedStrings (String(), false));
}
};
LeakAvoidanceTrick leakAvoidanceTrick;
#endif
SpinLock currentMappingsLock;
ScopedPointer<LocalisedStrings> currentMappings;
int findCloseQuote (const String& text, int startPos)
{
beast_wchar lastChar = 0;
String::CharPointerType t (text.getCharPointer() + startPos);
for (;;)
{
const beast_wchar c = t.getAndAdvance();
if (c == 0 || (c == '"' && lastChar != '\\'))
break;
lastChar = c;
++startPos;
}
return startPos;
}
String unescapeString (const String& s)
{
return s.replace ("\\\"", "\"")
.replace ("\\\'", "\'")
.replace ("\\t", "\t")
.replace ("\\r", "\r")
.replace ("\\n", "\n");
}
}
void LocalisedStrings::loadFromText (const String& fileContents, bool ignoreCase)
{
translations.setIgnoresCase (ignoreCase);
StringArray lines;
lines.addLines (fileContents);
for (int i = 0; i < lines.size(); ++i)
{
String line (lines[i].trim());
if (line.startsWithChar ('"'))
{
int closeQuote = findCloseQuote (line, 1);
const String originalText (unescapeString (line.substring (1, closeQuote)));
if (originalText.isNotEmpty())
{
const int openingQuote = findCloseQuote (line, closeQuote + 1);
closeQuote = findCloseQuote (line, openingQuote + 1);
const String newText (unescapeString (line.substring (openingQuote + 1, closeQuote)));
if (newText.isNotEmpty())
translations.set (originalText, newText);
}
}
else if (line.startsWithIgnoreCase ("language:"))
{
languageName = line.substring (9).trim();
}
else if (line.startsWithIgnoreCase ("countries:"))
{
countryCodes.addTokens (line.substring (10).trim(), true);
countryCodes.trim();
countryCodes.removeEmptyStrings();
}
}
}
//==============================================================================
void LocalisedStrings::setCurrentMappings (LocalisedStrings* newTranslations)
{
const SpinLock::ScopedLockType sl (currentMappingsLock);
currentMappings = newTranslations;
}
LocalisedStrings* LocalisedStrings::getCurrentMappings()
{
return currentMappings;
}
String LocalisedStrings::translateWithCurrentMappings (const String& text) { return beast::translate (text); }
String LocalisedStrings::translateWithCurrentMappings (const char* text) { return beast::translate (text); }
String translate (const String& text) { return beast::translate (text, text); }
String translate (const char* text) { return beast::translate (String (text)); }
String translate (CharPointer_UTF8 text) { return beast::translate (String (text)); }
String translate (const String& text, const String& resultIfNotFound)
{
const SpinLock::ScopedLockType sl (currentMappingsLock);
if (const LocalisedStrings* const mappings = LocalisedStrings::getCurrentMappings())
return mappings->translate (text, resultIfNotFound);
return resultIfNotFound;
}
} // namespace beast

View File

@@ -1,223 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_LOCALISEDSTRINGS_H_INCLUDED
#define BEAST_LOCALISEDSTRINGS_H_INCLUDED
namespace beast
{
//==============================================================================
/**
Used to convert strings to localised foreign-language versions.
This is basically a look-up table of strings and their translated equivalents.
It can be loaded from a text file, so that you can supply a set of localised
versions of strings that you use in your app.
To use it in your code, simply call the translate() method on each string that
might have foreign versions, and if none is found, the method will just return
the original string.
The translation file should start with some lines specifying a description of
the language it contains, and also a list of ISO country codes where it might
be appropriate to use the file. After that, each line of the file should contain
a pair of quoted strings with an '=' sign.
E.g. for a french translation, the file might be:
@code
language: French
countries: fr be mc ch lu
"hello" = "bonjour"
"goodbye" = "au revoir"
@endcode
If the strings need to contain a quote character, they can use '\"' instead, and
if the first non-whitespace character on a line isn't a quote, then it's ignored,
(you can use this to add comments).
Note that this is a singleton class, so don't create or destroy the object directly.
There's also a TRANS(text) macro defined to make it easy to use the this.
E.g. @code
printSomething (TRANS("hello"));
@endcode
This macro is used in the Juce classes themselves, so your application has a chance to
intercept and translate any internal Juce text strings that might be shown. (You can easily
get a list of all the messages by searching for the TRANS() macro in the Juce source
code).
*/
class BEAST_API LocalisedStrings : LeakChecked <LocalisedStrings>
{
public:
//==============================================================================
/** Creates a set of translations from the text of a translation file.
When you create one of these, you can call setCurrentMappings() to make it
the set of mappings that the system's using.
*/
LocalisedStrings (const String& fileContents,
bool ignoreCaseOfKeys);
/** Creates a set of translations from a file.
When you create one of these, you can call setCurrentMappings() to make it
the set of mappings that the system's using.
*/
LocalisedStrings (const File& fileToLoad,
bool ignoreCaseOfKeys);
/** Destructor. */
~LocalisedStrings();
//==============================================================================
/** Selects the current set of mappings to be used by the system.
The object you pass in will be automatically deleted when no longer needed, so
don't keep a pointer to it. You can also pass in zero to remove the current
mappings.
See also the TRANS() macro, which uses the current set to do its translation.
@see translateWithCurrentMappings
*/
static void setCurrentMappings (LocalisedStrings* newTranslations);
/** Returns the currently selected set of mappings.
This is the object that was last passed to setCurrentMappings(). It may
be nullptr if none has been created.
*/
static LocalisedStrings* getCurrentMappings();
/** Tries to translate a string using the currently selected set of mappings.
If no mapping has been set, or if the mapping doesn't contain a translation
for the string, this will just return the original string.
See also the TRANS() macro, which uses this method to do its translation.
@see setCurrentMappings, getCurrentMappings
*/
static String translateWithCurrentMappings (const String& text);
/** Tries to translate a string using the currently selected set of mappings.
If no mapping has been set, or if the mapping doesn't contain a translation
for the string, this will just return the original string.
See also the TRANS() macro, which uses this method to do its translation.
@see setCurrentMappings, getCurrentMappings
*/
static String translateWithCurrentMappings (const char* text);
//==============================================================================
/** Attempts to look up a string and return its localised version.
If the string isn't found in the list, the original string will be returned.
*/
String translate (const String& text) const;
/** Attempts to look up a string and return its localised version.
If the string isn't found in the list, the resultIfNotFound string will be returned.
*/
String translate (const String& text, const String& resultIfNotFound) const;
/** Returns the name of the language specified in the translation file.
This is specified in the file using a line starting with "language:", e.g.
@code
language: german
@endcode
*/
String getLanguageName() const { return languageName; }
/** Returns the list of suitable country codes listed in the translation file.
These is specified in the file using a line starting with "countries:", e.g.
@code
countries: fr be mc ch lu
@endcode
The country codes are supposed to be 2-character ISO complient codes.
*/
const StringArray& getCountryCodes() const { return countryCodes; }
/** Provides access to the actual list of mappings. */
const StringPairArray& getMappings() const { return translations; }
private:
//==============================================================================
String languageName;
StringArray countryCodes;
StringPairArray translations;
void loadFromText (const String&, bool ignoreCase);
};
//==============================================================================
#ifndef TRANS
/** Uses the LocalisedStrings class to translate the given string literal.
This macro is provided for backwards-compatibility, and just calls the translate()
function. In new code, it's recommended that you just call translate() directly
instead, and avoid using macros.
@see translate(), LocalisedStrings
*/
#define TRANS(stringLiteral) beast::translate (stringLiteral)
#endif
/** A dummy version of the TRANS macro, used to indicate a string literal that should be
added to the translation file by source-code scanner tools.
Wrapping a string literal in this macro has no effect, but by using it around strings
that your app needs to translate at a later stage, it lets automatic code-scanning tools
find this string and add it to the list of strings that need translation.
*/
#define NEEDS_TRANS(stringLiteral) (stringLiteral)
/** Uses the LocalisedStrings class to translate the given string literal.
@see LocalisedStrings
*/
String translate (const String& stringLiteral);
/** Uses the LocalisedStrings class to translate the given string literal.
@see LocalisedStrings
*/
String translate (const char* stringLiteral);
/** Uses the LocalisedStrings class to translate the given string literal.
@see LocalisedStrings
*/
String translate (CharPointer_UTF8 stringLiteral);
/** Uses the LocalisedStrings class to translate the given string literal.
@see LocalisedStrings
*/
String translate (const String& stringLiteral, const String& resultIfNotFound);
} // namespace beast
#endif // BEAST_LOCALISEDSTRINGS_H_INCLUDED

View File

@@ -1,114 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace beast
{
StringPool::StringPool() noexcept {}
StringPool::~StringPool() {}
namespace StringPoolHelpers
{
template <class StringType>
String::CharPointerType getPooledStringFromArray (Array<String>& strings,
StringType newString,
const CriticalSection& lock)
{
const ScopedLock sl (lock);
int start = 0;
int end = strings.size();
for (;;)
{
if (start >= end)
{
bassert (start <= end);
strings.insert (start, newString);
return strings.getReference (start).getCharPointer();
}
else
{
const String& startString = strings.getReference (start);
if (startString == newString)
return startString.getCharPointer();
const int halfway = (start + end) >> 1;
if (halfway == start)
{
if (startString.compare (newString) < 0)
++start;
strings.insert (start, newString);
return strings.getReference (start).getCharPointer();
}
const int comp = strings.getReference (halfway).compare (newString);
if (comp == 0)
return strings.getReference (halfway).getCharPointer();
else if (comp < 0)
start = halfway;
else
end = halfway;
}
}
}
}
String::CharPointerType StringPool::getPooledString (const String& s)
{
if (s.isEmpty())
return String::empty.getCharPointer();
return StringPoolHelpers::getPooledStringFromArray (strings, s, lock);
}
String::CharPointerType StringPool::getPooledString (const char* const s)
{
if (s == nullptr || *s == 0)
return String::empty.getCharPointer();
return StringPoolHelpers::getPooledStringFromArray (strings, s, lock);
}
String::CharPointerType StringPool::getPooledString (const wchar_t* const s)
{
if (s == nullptr || *s == 0)
return String::empty.getCharPointer();
return StringPoolHelpers::getPooledStringFromArray (strings, s, lock);
}
int StringPool::size() const noexcept
{
return strings.size();
}
String::CharPointerType StringPool::operator[] (const int index) const noexcept
{
return strings [index].getCharPointer();
}
} // namespace beast

View File

@@ -1,90 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_STRINGPOOL_H_INCLUDED
#define BEAST_STRINGPOOL_H_INCLUDED
namespace beast
{
//==============================================================================
/**
A StringPool holds a set of shared strings, which reduces storage overheads and improves
comparison speed when dealing with many duplicate strings.
When you add a string to a pool using getPooledString, it'll return a character
array containing the same string. This array is owned by the pool, and the same array
is returned every time a matching string is asked for. This means that it's trivial to
compare two pooled strings for equality, as you can simply compare their pointers. It
also cuts down on storage if you're using many copies of the same string.
*/
class BEAST_API StringPool
{
public:
//==============================================================================
/** Creates an empty pool. */
StringPool() noexcept;
/** Destructor */
~StringPool();
//==============================================================================
/** Returns a pointer to a copy of the string that is passed in.
The pool will always return the same pointer when asked for a string that matches it.
The pool will own all the pointers that it returns, deleting them when the pool itself
is deleted.
*/
String::CharPointerType getPooledString (const String& original);
/** Returns a pointer to a copy of the string that is passed in.
The pool will always return the same pointer when asked for a string that matches it.
The pool will own all the pointers that it returns, deleting them when the pool itself
is deleted.
*/
String::CharPointerType getPooledString (const char* original);
/** Returns a pointer to a copy of the string that is passed in.
The pool will always return the same pointer when asked for a string that matches it.
The pool will own all the pointers that it returns, deleting them when the pool itself
is deleted.
*/
String::CharPointerType getPooledString (const wchar_t* original);
//==============================================================================
/** Returns the number of strings in the pool. */
int size() const noexcept;
/** Returns one of the strings in the pool, by index. */
String::CharPointerType operator[] (int index) const noexcept;
private:
Array <String> strings;
CriticalSection lock;
};
} // namespace beast
#endif // BEAST_STRINGPOOL_H_INCLUDED

View File

@@ -114,11 +114,6 @@ int Workers::numberOfCurrentlyRunningTasks () const noexcept
return m_runningTaskCount.get ();
}
double Workers::getUtilization () const
{
return m_usage.getUtilization();
}
void Workers::deleteWorkers (LockFreeStack <Worker>& stack)
{
for (;;)
@@ -165,45 +160,37 @@ void Workers::Worker::run ()
{
// Acquire a task or "internal task."
//
m_workers.m_semaphore.wait ();
// See if there's a pause request. This
// counts as an "internal task."
//
int pauseCount = m_workers.m_pauseCount.get ();
if (pauseCount > 0)
{
CPUMeter::ScopedIdleTime elapsed (m_workers.m_usage);
// Try to decrement
pauseCount = --m_workers.m_pauseCount;
m_workers.m_semaphore.wait ();
}
{
CPUMeter::ScopedActiveTime elapsed (m_workers.m_usage);
// See if there's a pause request. This
// counts as an "internal task."
//
int pauseCount = m_workers.m_pauseCount.get ();
if (pauseCount > 0)
if (pauseCount >= 0)
{
// Try to decrement
pauseCount = --m_workers.m_pauseCount;
if (pauseCount >= 0)
{
// We got paused
break;
}
else
{
// Undo our decrement
++m_workers.m_pauseCount;
}
// We got paused
break;
}
else
{
// Undo our decrement
++m_workers.m_pauseCount;
}
// We couldn't pause so we must have gotten
// unblocked in order to process a task.
//
++m_workers.m_runningTaskCount;
m_workers.m_callback.processTask ();
--m_workers.m_runningTaskCount;
}
// We couldn't pause so we must have gotten
// unblocked in order to process a task.
//
++m_workers.m_runningTaskCount;
m_workers.m_callback.processTask ();
--m_workers.m_runningTaskCount;
// Put the name back in case the callback changed it
Thread::setCurrentThreadName (Thread::getThreadName());
}

View File

@@ -96,9 +96,6 @@ public:
*/
int numberOfCurrentlyRunningTasks () const noexcept;
/** Returns the fraction of time that the CPU is being used. */
double getUtilization () const;
//--------------------------------------------------------------------------
private:
@@ -134,7 +131,6 @@ private:
private:
Callback& m_callback;
CPUMeter m_usage; // CPU utilization across threads
String m_threadNames; // The name to give each thread
WaitableEvent m_allPaused; // signaled when all threads paused
semaphore m_semaphore; // each pending task is 1 resource

View File

@@ -1,34 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace beast
{
SpinDelay::SpinDelay ()
: m_count (0)
{
}
void SpinDelay::pause ()
{
if (++m_count > 20)
Thread::yield ();
}
} // namespace beast

View File

@@ -1,41 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_SPINDELAY_H_INCLUDED
#define BEAST_SPINDELAY_H_INCLUDED
namespace beast
{
/** A simple delay used to synchronize threads.
*/
class BEAST_API SpinDelay
{
public:
SpinDelay ();
void pause ();
private:
int m_count;
};
} // namespace beast
#endif

View File

@@ -1,95 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace beast
{
PerformanceCounter::PerformanceCounter (const String& name_,
const int runsPerPrintout,
const File& loggingFile)
: name (name_),
numRuns (0),
runsPerPrint (runsPerPrintout),
totalTime (0),
outputFile (loggingFile)
{
if (outputFile != File::nonexistent ())
{
String s ("**** Counter for \"");
s << name_ << "\" started at: "
<< Time::getCurrentTime().toString (true, true)
<< newLine;
outputFile.appendText (s, false, false);
}
}
PerformanceCounter::~PerformanceCounter()
{
printStatistics();
}
void PerformanceCounter::start()
{
started = Time::getHighResolutionTicks();
}
void PerformanceCounter::stop()
{
const int64 now = Time::getHighResolutionTicks();
totalTime += 1000.0 * Time::highResolutionTicksToSeconds (now - started);
if (++numRuns == runsPerPrint)
printStatistics();
}
void PerformanceCounter::printStatistics()
{
if (numRuns > 0)
{
String s ("Performance count for \"");
s << name << "\" - average over " << numRuns << " run(s) = ";
const int micros = (int) (totalTime * (1000.0 / numRuns));
if (micros > 10000)
s << (micros/1000) << " millisecs";
else
s << micros << " microsecs";
s << ", total = " << String (totalTime / 1000, 5) << " seconds";
Logger::outputDebugString (s);
s << newLine;
if (outputFile != File::nonexistent ())
outputFile.appendText (s, false, false);
numRuns = 0;
totalTime = 0;
}
}
} // namespace beast

View File

@@ -1,106 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_PERFORMANCECOUNTER_H_INCLUDED
#define BEAST_PERFORMANCECOUNTER_H_INCLUDED
namespace beast
{
//==============================================================================
/** A timer for measuring performance of code and dumping the results to a file.
e.g. @code
PerformanceCounter pc ("fish", 50, "/temp/myfishlog.txt");
for (;;)
{
pc.start();
doSomethingFishy();
pc.stop();
}
@endcode
In this example, the time of each period between calling start/stop will be
measured and averaged over 50 runs, and the results printed to a file
every 50 times round the loop.
*/
class BEAST_API PerformanceCounter
{
public:
//==============================================================================
/** Creates a PerformanceCounter object.
@param counterName the name used when printing out the statistics
@param runsPerPrintout the number of start/stop iterations before calling
printStatistics()
@param loggingFile a file to dump the results to - if this is
File::nonexistent (), the results are just written
to the debugger output
*/
PerformanceCounter (const String& counterName,
int runsPerPrintout = 100,
const File& loggingFile = File::nonexistent ());
/** Destructor. */
~PerformanceCounter();
//==============================================================================
/** Starts timing.
@see stop
*/
void start();
/** Stops timing and prints out the results.
The number of iterations before doing a printout of the
results is set in the constructor.
@see start
*/
void stop();
/** Dumps the current metrics to the debugger output and to a file.
As well as using Logger::outputDebugString to print the results,
this will write then to the file specified in the constructor (if
this was valid).
*/
void printStatistics();
private:
//==============================================================================
String name;
int numRuns, runsPerPrint;
double totalTime;
int64 started;
File outputFile;
};
} // namespace beast
#endif // BEAST_PERFORMANCECOUNTER_H_INCLUDED

View File

@@ -412,8 +412,8 @@ String Time::getMonthName (int monthNumber, const bool threeLetterVersion)
monthNumber %= 12;
return TRANS (threeLetterVersion ? shortMonthNames [monthNumber]
: longMonthNames [monthNumber]);
return threeLetterVersion ? shortMonthNames [monthNumber]
: longMonthNames [monthNumber];
}
String Time::getWeekdayName (int day, const bool threeLetterVersion)
@@ -423,8 +423,8 @@ String Time::getWeekdayName (int day, const bool threeLetterVersion)
day %= 7;
return TRANS (threeLetterVersion ? shortDayNames [day]
: longDayNames [day]);
return threeLetterVersion ? shortDayNames [day]
: longDayNames [day];
}
//==============================================================================

View File

@@ -24,8 +24,9 @@
#ifndef BEAST_TIME_H_INCLUDED
#define BEAST_TIME_H_INCLUDED
namespace beast
{
#include "../../../beast/chrono/RelativeTime.h"
namespace beast {
//==============================================================================
/**

View File

@@ -27,6 +27,8 @@
namespace beast
{
class XmlElement;
//==============================================================================
/**
Parses a text-based XML document and creates an XmlElement object from it.

View File

@@ -1,213 +0,0 @@
/*
==============================================================================
This file is part of the beast_core module of the BEAST library.
Copyright (c) 2013 - Raw Material Software Ltd.
Permission to use, copy, modify, and/or distribute this software for any purpose with
or without fee is hereby granted, provided that the above copyright notice and this
permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
------------------------------------------------------------------------------
NOTE! This permissive ISC license applies ONLY to files within the beast_core module!
All other BEAST modules are covered by a dual GPL/commercial license, so if you are
using any other modules, be sure to check that you also comply with their license.
For more details, visit www.beast.com
==============================================================================
*/
namespace beast
{
class GZIPCompressorOutputStream::GZIPCompressorHelper : public Uncopyable
{
public:
GZIPCompressorHelper (const int compressionLevel, const int windowBits)
: compLevel ((compressionLevel < 1 || compressionLevel > 9) ? -1 : compressionLevel),
isFirstDeflate (true),
streamIsValid (false),
finished (false)
{
using namespace zlibNamespace;
zerostruct (stream);
streamIsValid = (deflateInit2 (&stream, compLevel, Z_DEFLATED,
windowBits != 0 ? windowBits : MAX_WBITS,
8, strategy) == Z_OK);
}
~GZIPCompressorHelper()
{
if (streamIsValid)
zlibNamespace::deflateEnd (&stream);
}
bool write (const uint8* data, size_t dataSize, OutputStream& out)
{
// When you call flush() on a gzip stream, the stream is closed, and you can
// no longer continue to write data to it!
bassert (! finished);
while (dataSize > 0)
if (! doNextBlock (data, dataSize, out, Z_NO_FLUSH))
return false;
return true;
}
void finish (OutputStream& out)
{
const uint8* data = nullptr;
size_t dataSize = 0;
while (! finished)
doNextBlock (data, dataSize, out, Z_FINISH);
}
private:
enum { strategy = 0 };
zlibNamespace::z_stream stream;
const int compLevel;
bool isFirstDeflate, streamIsValid, finished;
zlibNamespace::Bytef buffer[32768];
bool doNextBlock (const uint8*& data, size_t& dataSize, OutputStream& out, const int flushMode)
{
using namespace zlibNamespace;
if (streamIsValid)
{
stream.next_in = const_cast <uint8*> (data);
stream.next_out = buffer;
stream.avail_in = (z_uInt) dataSize;
stream.avail_out = (z_uInt) sizeof (buffer);
const int result = isFirstDeflate ? deflateParams (&stream, compLevel, strategy)
: deflate (&stream, flushMode);
isFirstDeflate = false;
switch (result)
{
case Z_STREAM_END:
finished = true;
// Deliberate fall-through..
case Z_OK:
{
data += dataSize - stream.avail_in;
dataSize = stream.avail_in;
const ssize_t bytesDone = (ssize_t) sizeof (buffer) - (ssize_t) stream.avail_out;
return bytesDone <= 0 || out.write (buffer, (size_t) bytesDone);
}
default:
break;
}
}
return false;
}
};
//==============================================================================
GZIPCompressorOutputStream::GZIPCompressorOutputStream (OutputStream* const out,
const int compressionLevel,
const bool deleteDestStream,
const int windowBits)
: destStream (out, deleteDestStream),
helper (new GZIPCompressorHelper (compressionLevel, windowBits))
{
bassert (out != nullptr);
}
GZIPCompressorOutputStream::~GZIPCompressorOutputStream()
{
flush();
}
void GZIPCompressorOutputStream::flush()
{
helper->finish (*destStream);
destStream->flush();
}
bool GZIPCompressorOutputStream::write (const void* destBuffer, size_t howMany)
{
bassert (destBuffer != nullptr && (ssize_t) howMany >= 0);
return helper->write (static_cast <const uint8*> (destBuffer), howMany, *destStream);
}
int64 GZIPCompressorOutputStream::getPosition()
{
return destStream->getPosition();
}
bool GZIPCompressorOutputStream::setPosition (int64 /*newPosition*/)
{
bassertfalse; // can't do it!
return false;
}
//==============================================================================
class GZIPTests : public UnitTest
{
public:
GZIPTests() : UnitTest ("GZIP", "beast") {}
void runTest()
{
beginTestCase ("GZIP");
Random rng;
for (int i = 100; --i >= 0;)
{
MemoryOutputStream original, compressed, uncompressed;
{
GZIPCompressorOutputStream zipper (&compressed, rng.nextInt (10), false);
for (int j = rng.nextInt (100); --j >= 0;)
{
MemoryBlock data ((unsigned int) (rng.nextInt (2000) + 1));
for (int k = (int) data.getSize(); --k >= 0;)
data[k] = (char) rng.nextInt (255);
original << data;
zipper << data;
}
}
{
MemoryInputStream compressedInput (compressed.getData(), compressed.getDataSize(), false);
GZIPDecompressorInputStream unzipper (compressedInput);
uncompressed << unzipper;
}
expectEquals ((int) uncompressed.getDataSize(),
(int) original.getDataSize());
if (original.getDataSize() == uncompressed.getDataSize())
expect (memcmp (uncompressed.getData(),
original.getData(),
original.getDataSize()) == 0);
}
}
};
static GZIPTests gzipTests;
} // namespace beast

View File

@@ -1,105 +0,0 @@
/*
==============================================================================
This file is part of the beast_core module of the BEAST library.
Copyright (c) 2013 - Raw Material Software Ltd.
Permission to use, copy, modify, and/or distribute this software for any purpose with
or without fee is hereby granted, provided that the above copyright notice and this
permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
------------------------------------------------------------------------------
NOTE! This permissive ISC license applies ONLY to files within the beast_core module!
All other BEAST modules are covered by a dual GPL/commercial license, so if you are
using any other modules, be sure to check that you also comply with their license.
For more details, visit www.beast.com
==============================================================================
*/
#ifndef BEAST_GZIPCOMPRESSOROUTPUTSTREAM_H_INCLUDED
#define BEAST_GZIPCOMPRESSOROUTPUTSTREAM_H_INCLUDED
namespace beast
{
//==============================================================================
/**
A stream which uses zlib to compress the data written into it.
Important note: When you call flush() on a GZIPCompressorOutputStream,
the gzip data is closed - this means that no more data can be written to
it, and any subsequent attempts to call write() will cause an assertion.
@see GZIPDecompressorInputStream
*/
class BEAST_API GZIPCompressorOutputStream
: public OutputStream
, LeakChecked <GZIPCompressorOutputStream>
{
public:
//==============================================================================
/** Creates a compression stream.
@param destStream the stream into which the compressed data should
be written
@param compressionLevel how much to compress the data, between 1 and 9, where
1 is the fastest/lowest compression, and 9 is the
slowest/highest compression. Any value outside this range
indicates that a default compression level should be used.
@param deleteDestStreamWhenDestroyed whether or not to delete the destStream object when
this stream is destroyed
@param windowBits this is used internally to change the window size used
by zlib - leave it as 0 unless you specifically need to set
its value for some reason
*/
GZIPCompressorOutputStream (OutputStream* destStream,
int compressionLevel = 0,
bool deleteDestStreamWhenDestroyed = false,
int windowBits = 0);
/** Destructor. */
~GZIPCompressorOutputStream();
//==============================================================================
/** Flushes and closes the stream.
Note that unlike most streams, when you call flush() on a GZIPCompressorOutputStream,
the stream is closed - this means that no more data can be written to it, and any
subsequent attempts to call write() will cause an assertion.
*/
void flush();
int64 getPosition() override;
bool setPosition (int64) override;
bool write (const void*, size_t) override;
/** These are preset values that can be used for the constructor's windowBits paramter.
For more info about this, see the zlib documentation for its windowBits parameter.
*/
enum WindowBitsValues
{
windowBitsRaw = -15,
windowBitsGZIP = 15 + 16
};
private:
//==============================================================================
OptionalScopedPointer<OutputStream> destStream;
class GZIPCompressorHelper;
friend class ScopedPointer <GZIPCompressorHelper>;
ScopedPointer <GZIPCompressorHelper> helper;
};
} // namespace beast
#endif // BEAST_GZIPCOMPRESSOROUTPUTSTREAM_H_INCLUDED

View File

@@ -1,297 +0,0 @@
/*
==============================================================================
This file is part of the beast_core module of the BEAST library.
Copyright (c) 2013 - Raw Material Software Ltd.
Permission to use, copy, modify, and/or distribute this software for any purpose with
or without fee is hereby granted, provided that the above copyright notice and this
permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
------------------------------------------------------------------------------
NOTE! This permissive ISC license applies ONLY to files within the beast_core module!
All other BEAST modules are covered by a dual GPL/commercial license, so if you are
using any other modules, be sure to check that you also comply with their license.
For more details, visit www.beast.com
==============================================================================
*/
namespace beast
{
#if BEAST_MSVC
#pragma warning (push)
#pragma warning (disable: 4309 4305 4365)
#endif
namespace zlibNamespace
{
#if BEAST_INCLUDE_ZLIB_CODE
#if BEAST_CLANG
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
#pragma clang diagnostic ignored "-Wshadow"
#endif
#undef OS_CODE
#undef fdopen
#define ZLIB_INTERNAL
#define NO_DUMMY_DECL
#include "zlib/zlib.h"
#include "zlib/adler32.c"
#include "zlib/compress.c"
#undef DO1
#undef DO8
#include "zlib/crc32.c"
#include "zlib/deflate.c"
#include "zlib/inffast.c"
#undef PULLBYTE
#undef LOAD
#undef RESTORE
#undef INITBITS
#undef NEEDBITS
#undef DROPBITS
#undef BYTEBITS
#include "zlib/inflate.c"
#include "zlib/inftrees.c"
#include "zlib/trees.c"
#include "zlib/zutil.c"
#undef Byte
#undef fdopen
#undef local
#undef Code
#undef Dad
#undef Len
#undef Freq
#if BEAST_CLANG
#pragma clang diagnostic pop
#endif
#else
#include BEAST_ZLIB_INCLUDE_PATH
#endif
}
#if BEAST_MSVC
#pragma warning (pop)
#endif
//==============================================================================
// internal helper object that holds the zlib structures so they don't have to be
// included publicly.
class GZIPDecompressorInputStream::GZIPDecompressHelper : public Uncopyable
{
public:
GZIPDecompressHelper (const bool dontWrap)
: finished (true),
needsDictionary (false),
error (true),
streamIsValid (false),
data (nullptr),
dataSize (0)
{
using namespace zlibNamespace;
zerostruct (stream);
streamIsValid = (inflateInit2 (&stream, dontWrap ? -MAX_WBITS : MAX_WBITS) == Z_OK);
finished = error = ! streamIsValid;
}
~GZIPDecompressHelper()
{
using namespace zlibNamespace;
if (streamIsValid)
inflateEnd (&stream);
}
bool needsInput() const noexcept { return dataSize <= 0; }
void setInput (uint8* const data_, const size_t size) noexcept
{
data = data_;
dataSize = size;
}
int doNextBlock (uint8* const dest, const unsigned int destSize)
{
using namespace zlibNamespace;
if (streamIsValid && data != nullptr && ! finished)
{
stream.next_in = data;
stream.next_out = dest;
stream.avail_in = (z_uInt) dataSize;
stream.avail_out = (z_uInt) destSize;
switch (inflate (&stream, Z_PARTIAL_FLUSH))
{
case Z_STREAM_END:
finished = true;
// deliberate fall-through
case Z_OK:
data += dataSize - stream.avail_in;
dataSize = (z_uInt) stream.avail_in;
return (int) (destSize - stream.avail_out);
case Z_NEED_DICT:
needsDictionary = true;
data += dataSize - stream.avail_in;
dataSize = (size_t) stream.avail_in;
break;
case Z_DATA_ERROR:
case Z_MEM_ERROR:
error = true;
default:
break;
}
}
return 0;
}
bool finished, needsDictionary, error, streamIsValid;
enum { gzipDecompBufferSize = 32768 };
private:
zlibNamespace::z_stream stream;
uint8* data;
size_t dataSize;
};
//==============================================================================
GZIPDecompressorInputStream::GZIPDecompressorInputStream (InputStream* const sourceStream_,
const bool deleteSourceWhenDestroyed,
const bool noWrap_,
const int64 uncompressedStreamLength_)
: sourceStream (sourceStream_, deleteSourceWhenDestroyed),
uncompressedStreamLength (uncompressedStreamLength_),
noWrap (noWrap_),
isEof (false),
activeBufferSize (0),
originalSourcePos (sourceStream_->getPosition()),
currentPos (0),
buffer ((size_t) GZIPDecompressHelper::gzipDecompBufferSize),
helper (new GZIPDecompressHelper (noWrap_))
{
}
GZIPDecompressorInputStream::GZIPDecompressorInputStream (InputStream& sourceStream_)
: sourceStream (&sourceStream_, false),
uncompressedStreamLength (-1),
noWrap (false),
isEof (false),
activeBufferSize (0),
originalSourcePos (sourceStream_.getPosition()),
currentPos (0),
buffer ((size_t) GZIPDecompressHelper::gzipDecompBufferSize),
helper (new GZIPDecompressHelper (false))
{
}
GZIPDecompressorInputStream::~GZIPDecompressorInputStream()
{
}
int64 GZIPDecompressorInputStream::getTotalLength()
{
return uncompressedStreamLength;
}
int GZIPDecompressorInputStream::read (void* destBuffer, int howMany)
{
bassert (destBuffer != nullptr && howMany >= 0);
if (howMany > 0 && ! isEof)
{
int numRead = 0;
uint8* d = static_cast <uint8*> (destBuffer);
while (! helper->error)
{
const int n = helper->doNextBlock (d, (unsigned int) howMany);
currentPos += n;
if (n == 0)
{
if (helper->finished || helper->needsDictionary)
{
isEof = true;
return numRead;
}
if (helper->needsInput())
{
activeBufferSize = sourceStream->read (buffer, (int) GZIPDecompressHelper::gzipDecompBufferSize);
if (activeBufferSize > 0)
{
helper->setInput (buffer, (size_t) activeBufferSize);
}
else
{
isEof = true;
return numRead;
}
}
}
else
{
numRead += n;
howMany -= n;
d += n;
if (howMany <= 0)
return numRead;
}
}
}
return 0;
}
bool GZIPDecompressorInputStream::isExhausted()
{
return helper->error || isEof;
}
int64 GZIPDecompressorInputStream::getPosition()
{
return currentPos;
}
bool GZIPDecompressorInputStream::setPosition (int64 newPos)
{
if (newPos < currentPos)
{
// to go backwards, reset the stream and start again..
isEof = false;
activeBufferSize = 0;
currentPos = 0;
helper = new GZIPDecompressHelper (noWrap);
sourceStream->setPosition (originalSourcePos);
}
skipNextBytes (newPos - currentPos);
return true;
}
// (This is used as a way for the zip file code to use the crc32 function without including zlib)
unsigned long beast_crc32 (unsigned long, const unsigned char*, unsigned);
unsigned long beast_crc32 (unsigned long crc, const unsigned char* buf, unsigned len)
{
return zlibNamespace::crc32 (crc, buf, len);
}
} // namespace beast

View File

@@ -1,102 +0,0 @@
/*
==============================================================================
This file is part of the beast_core module of the BEAST library.
Copyright (c) 2013 - Raw Material Software Ltd.
Permission to use, copy, modify, and/or distribute this software for any purpose with
or without fee is hereby granted, provided that the above copyright notice and this
permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
------------------------------------------------------------------------------
NOTE! This permissive ISC license applies ONLY to files within the beast_core module!
All other BEAST modules are covered by a dual GPL/commercial license, so if you are
using any other modules, be sure to check that you also comply with their license.
For more details, visit www.beast.com
==============================================================================
*/
#ifndef BEAST_GZIPDECOMPRESSORINPUTSTREAM_H_INCLUDED
#define BEAST_GZIPDECOMPRESSORINPUTSTREAM_H_INCLUDED
namespace beast
{
//==============================================================================
/**
This stream will decompress a source-stream using zlib.
Tip: if you're reading lots of small items from one of these streams, you
can increase the performance enormously by passing it through a
BufferedInputStream, so that it has to read larger blocks less often.
@see GZIPCompressorOutputStream
*/
class BEAST_API GZIPDecompressorInputStream
: public InputStream
, LeakChecked <GZIPDecompressorInputStream>
{
public:
//==============================================================================
/** Creates a decompressor stream.
@param sourceStream the stream to read from
@param deleteSourceWhenDestroyed whether or not to delete the source stream
when this object is destroyed
@param noWrap this is used internally by the ZipFile class
and should be ignored by user applications
@param uncompressedStreamLength if the creator knows the length that the
uncompressed stream will be, then it can supply this
value, which will be returned by getTotalLength()
*/
GZIPDecompressorInputStream (InputStream* sourceStream,
bool deleteSourceWhenDestroyed,
bool noWrap = false,
int64 uncompressedStreamLength = -1);
/** Creates a decompressor stream.
@param sourceStream the stream to read from - the source stream must not be
deleted until this object has been destroyed
*/
GZIPDecompressorInputStream (InputStream& sourceStream);
/** Destructor. */
~GZIPDecompressorInputStream();
//==============================================================================
int64 getPosition();
bool setPosition (int64 pos);
int64 getTotalLength();
bool isExhausted();
int read (void* destBuffer, int maxBytesToRead);
//==============================================================================
private:
OptionalScopedPointer<InputStream> sourceStream;
const int64 uncompressedStreamLength;
const bool noWrap;
bool isEof;
int activeBufferSize;
int64 originalSourcePos, currentPos;
HeapBlock <uint8> buffer;
class GZIPDecompressHelper;
friend class ScopedPointer <GZIPDecompressHelper>;
ScopedPointer <GZIPDecompressHelper> helper;
};
} // namespace beast
#endif // BEAST_GZIPDECOMPRESSORINPUTSTREAM_H_INCLUDED

View File

@@ -1,600 +0,0 @@
/*
==============================================================================
This file is part of the beast_core module of the BEAST library.
Copyright (c) 2013 - Raw Material Software Ltd.
Permission to use, copy, modify, and/or distribute this software for any purpose with
or without fee is hereby granted, provided that the above copyright notice and this
permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
------------------------------------------------------------------------------
NOTE! This permissive ISC license applies ONLY to files within the beast_core module!
All other BEAST modules are covered by a dual GPL/commercial license, so if you are
using any other modules, be sure to check that you also comply with their license.
For more details, visit www.beast.com
==============================================================================
*/
namespace beast
{
class ZipFile::ZipEntryHolder
{
public:
ZipEntryHolder (const char* const buffer, const int fileNameLen)
{
entry.filename = String::fromUTF8 (buffer + 46, fileNameLen);
const int time = ByteOrder::littleEndianShort (buffer + 12);
const int date = ByteOrder::littleEndianShort (buffer + 14);
entry.fileTime = getFileTimeFromRawEncodings (time, date);
compressed = ByteOrder::littleEndianShort (buffer + 10) != 0;
compressedSize = (size_t) ByteOrder::littleEndianInt (buffer + 20);
entry.uncompressedSize = ByteOrder::littleEndianInt (buffer + 24);
streamOffset = ByteOrder::littleEndianInt (buffer + 42);
}
struct FileNameComparator
{
static int compareElements (const ZipEntryHolder* first, const ZipEntryHolder* second)
{
return first->entry.filename.compare (second->entry.filename);
}
};
ZipEntry entry;
size_t streamOffset;
size_t compressedSize;
bool compressed;
private:
static Time getFileTimeFromRawEncodings (int time, int date)
{
const int year = 1980 + (date >> 9);
const int month = ((date >> 5) & 15) - 1;
const int day = date & 31;
const int hours = time >> 11;
const int minutes = (time >> 5) & 63;
const int seconds = (time & 31) << 1;
return Time (year, month, day, hours, minutes, seconds);
}
};
//==============================================================================
namespace
{
int findEndOfZipEntryTable (InputStream& input, int& numEntries)
{
BufferedInputStream in (input, 8192);
in.setPosition (in.getTotalLength());
int64 pos = in.getPosition();
const int64 lowestPos = bmax ((int64) 0, pos - 1024);
char buffer [32] = { 0 };
while (pos > lowestPos)
{
in.setPosition (pos - 22);
pos = in.getPosition();
memcpy (buffer + 22, buffer, 4);
if (in.read (buffer, 22) != 22)
return 0;
for (int i = 0; i < 22; ++i)
{
if (ByteOrder::littleEndianInt (buffer + i) == 0x06054b50)
{
in.setPosition (pos + i);
in.read (buffer, 22);
numEntries = ByteOrder::littleEndianShort (buffer + 10);
return (int) ByteOrder::littleEndianInt (buffer + 16);
}
}
}
return 0;
}
}
//==============================================================================
class ZipFile::ZipInputStream
: public InputStream
, LeakChecked <ZipInputStream>
{
public:
ZipInputStream (ZipFile& zf, ZipFile::ZipEntryHolder& zei)
: file (zf),
zipEntryHolder (zei),
pos (0),
headerSize (0),
inputStream (zf.inputStream)
{
if (zf.inputSource != nullptr)
{
inputStream = streamToDelete = file.inputSource->createInputStream();
}
else
{
#if BEAST_DEBUG
zf.streamCounter.numOpenStreams++;
#endif
}
char buffer [30];
if (inputStream != nullptr
&& inputStream->setPosition (zei.streamOffset)
&& inputStream->read (buffer, 30) == 30
&& ByteOrder::littleEndianInt (buffer) == 0x04034b50)
{
headerSize = 30 + ByteOrder::littleEndianShort (buffer + 26)
+ ByteOrder::littleEndianShort (buffer + 28);
}
}
~ZipInputStream()
{
#if BEAST_DEBUG
if (inputStream != nullptr && inputStream == file.inputStream)
file.streamCounter.numOpenStreams--;
#endif
}
int64 getTotalLength()
{
return zipEntryHolder.compressedSize;
}
int read (void* buffer, int howMany)
{
if (headerSize <= 0)
return 0;
howMany = (int) bmin ((int64) howMany, (int64) (zipEntryHolder.compressedSize - pos));
if (inputStream == nullptr)
return 0;
int num;
if (inputStream == file.inputStream)
{
const ScopedLock sl (file.lock);
inputStream->setPosition (pos + zipEntryHolder.streamOffset + headerSize);
num = inputStream->read (buffer, howMany);
}
else
{
inputStream->setPosition (pos + zipEntryHolder.streamOffset + headerSize);
num = inputStream->read (buffer, howMany);
}
pos += num;
return num;
}
bool isExhausted()
{
return headerSize <= 0 || pos >= (int64) zipEntryHolder.compressedSize;
}
int64 getPosition()
{
return pos;
}
bool setPosition (int64 newPos)
{
pos = blimit ((int64) 0, (int64) zipEntryHolder.compressedSize, newPos);
return true;
}
private:
ZipFile& file;
ZipEntryHolder zipEntryHolder;
int64 pos;
int headerSize;
InputStream* inputStream;
ScopedPointer<InputStream> streamToDelete;
};
//==============================================================================
ZipFile::ZipFile (InputStream* const stream, const bool deleteStreamWhenDestroyed)
: inputStream (stream)
{
if (deleteStreamWhenDestroyed)
streamToDelete = inputStream;
init();
}
ZipFile::ZipFile (InputStream& stream)
: inputStream (&stream)
{
init();
}
ZipFile::ZipFile (const File& file)
: inputStream (nullptr),
inputSource (new FileInputSource (file))
{
init();
}
ZipFile::ZipFile (InputSource* const source)
: inputStream (nullptr),
inputSource (source)
{
init();
}
ZipFile::~ZipFile()
{
entries.clear();
}
#if BEAST_DEBUG
ZipFile::OpenStreamCounter::~OpenStreamCounter()
{
/* If you hit this assertion, it means you've created a stream to read one of the items in the
zipfile, but you've forgotten to delete that stream object before deleting the file..
Streams can't be kept open after the file is deleted because they need to share the input
stream that is managed by the ZipFile object.
*/
bassert (numOpenStreams == 0);
}
#endif
//==============================================================================
int ZipFile::getNumEntries() const noexcept
{
return entries.size();
}
const ZipFile::ZipEntry* ZipFile::getEntry (const int index) const noexcept
{
if (ZipEntryHolder* const zei = entries [index])
return &(zei->entry);
return nullptr;
}
int ZipFile::getIndexOfFileName (const String& fileName) const noexcept
{
for (int i = 0; i < entries.size(); ++i)
if (entries.getUnchecked (i)->entry.filename == fileName)
return i;
return -1;
}
const ZipFile::ZipEntry* ZipFile::getEntry (const String& fileName) const noexcept
{
return getEntry (getIndexOfFileName (fileName));
}
InputStream* ZipFile::createStreamForEntry (const int index)
{
InputStream* stream = nullptr;
if (ZipEntryHolder* const zei = entries[index])
{
stream = new ZipInputStream (*this, *zei);
if (zei->compressed)
{
stream = new GZIPDecompressorInputStream (stream, true, true,
zei->entry.uncompressedSize);
// (much faster to unzip in big blocks using a buffer..)
stream = new BufferedInputStream (stream, 32768, true);
}
}
return stream;
}
InputStream* ZipFile::createStreamForEntry (const ZipEntry& entry)
{
for (int i = 0; i < entries.size(); ++i)
if (&entries.getUnchecked (i)->entry == &entry)
return createStreamForEntry (i);
return nullptr;
}
void ZipFile::sortEntriesByFilename()
{
ZipEntryHolder::FileNameComparator sorter;
entries.sort (sorter);
}
//==============================================================================
void ZipFile::init()
{
ScopedPointer <InputStream> toDelete;
InputStream* in = inputStream;
if (inputSource != nullptr)
{
in = inputSource->createInputStream();
toDelete = in;
}
if (in != nullptr)
{
int numEntries = 0;
int pos = findEndOfZipEntryTable (*in, numEntries);
if (pos >= 0 && pos < in->getTotalLength())
{
const int size = (int) (in->getTotalLength() - pos);
in->setPosition (pos);
MemoryBlock headerData;
if (in->readIntoMemoryBlock (headerData, size) == size)
{
pos = 0;
for (int i = 0; i < numEntries; ++i)
{
if (pos + 46 > size)
break;
const char* const buffer = static_cast <const char*> (headerData.getData()) + pos;
const int fileNameLen = ByteOrder::littleEndianShort (buffer + 28);
if (pos + 46 + fileNameLen > size)
break;
entries.add (new ZipEntryHolder (buffer, fileNameLen));
pos += 46 + fileNameLen
+ ByteOrder::littleEndianShort (buffer + 30)
+ ByteOrder::littleEndianShort (buffer + 32);
}
}
}
}
}
Result ZipFile::uncompressTo (const File& targetDirectory,
const bool shouldOverwriteFiles)
{
for (int i = 0; i < entries.size(); ++i)
{
Result result (uncompressEntry (i, targetDirectory, shouldOverwriteFiles));
if (result.failed())
return result;
}
return Result::ok();
}
Result ZipFile::uncompressEntry (const int index,
const File& targetDirectory,
bool shouldOverwriteFiles)
{
const ZipEntryHolder* zei = entries.getUnchecked (index);
#if BEAST_WINDOWS
const String entryPath (zei->entry.filename);
#else
const String entryPath (zei->entry.filename.replaceCharacter ('\\', '/'));
#endif
const File targetFile (targetDirectory.getChildFile (entryPath));
if (entryPath.endsWithChar ('/') || entryPath.endsWithChar ('\\'))
return targetFile.createDirectory(); // (entry is a directory, not a file)
ScopedPointer<InputStream> in (createStreamForEntry (index));
if (in == nullptr)
return Result::fail ("Failed to open the zip file for reading");
if (targetFile.exists())
{
if (! shouldOverwriteFiles)
return Result::ok();
if (! targetFile.deleteFile())
return Result::fail ("Failed to write to target file: " + targetFile.getFullPathName());
}
if (! targetFile.getParentDirectory().createDirectory())
return Result::fail ("Failed to create target folder: " + targetFile.getParentDirectory().getFullPathName());
{
FileOutputStream out (targetFile);
if (out.failedToOpen())
return Result::fail ("Failed to write to target file: " + targetFile.getFullPathName());
out << *in;
}
targetFile.setCreationTime (zei->entry.fileTime);
targetFile.setLastModificationTime (zei->entry.fileTime);
targetFile.setLastAccessTime (zei->entry.fileTime);
return Result::ok();
}
//=============================================================================
extern unsigned long beast_crc32 (unsigned long crc, const unsigned char*, unsigned len);
class ZipFile::Builder::Item : LeakChecked <ZipFile::Builder::Item>, public Uncopyable
{
public:
Item (const File& f, const int compression, const String& storedPath)
: file (f),
storedPathname (storedPath.isEmpty() ? f.getFileName() : storedPath),
compressionLevel (compression),
compressedSize (0),
headerStart (0)
{
}
bool writeData (OutputStream& target, const int64 overallStartPosition)
{
MemoryOutputStream compressedData;
if (compressionLevel > 0)
{
GZIPCompressorOutputStream compressor (&compressedData, compressionLevel, false,
GZIPCompressorOutputStream::windowBitsRaw);
if (! writeSource (compressor))
return false;
}
else
{
if (! writeSource (compressedData))
return false;
}
compressedSize = (int) compressedData.getDataSize();
headerStart = (int) (target.getPosition() - overallStartPosition);
target.writeInt (0x04034b50);
writeFlagsAndSizes (target);
target << storedPathname
<< compressedData;
return true;
}
bool writeDirectoryEntry (OutputStream& target)
{
target.writeInt (0x02014b50);
target.writeShort (20); // version written
writeFlagsAndSizes (target);
target.writeShort (0); // comment length
target.writeShort (0); // start disk num
target.writeShort (0); // internal attributes
target.writeInt (0); // external attributes
target.writeInt (headerStart);
target << storedPathname;
return true;
}
private:
const File file;
String storedPathname;
int compressionLevel, compressedSize, headerStart;
unsigned long checksum;
void writeTimeAndDate (OutputStream& target) const
{
const Time t (file.getLastModificationTime());
target.writeShort ((short) (t.getSeconds() + (t.getMinutes() << 5) + (t.getHours() << 11)));
target.writeShort ((short) (t.getDayOfMonth() + ((t.getMonth() + 1) << 5) + ((t.getYear() - 1980) << 9)));
}
bool writeSource (OutputStream& target)
{
checksum = 0;
FileInputStream input (file);
if (input.failedToOpen())
return false;
const int bufferSize = 2048;
HeapBlock<unsigned char> buffer (bufferSize);
while (! input.isExhausted())
{
const int bytesRead = input.read (buffer, bufferSize);
if (bytesRead < 0)
return false;
checksum = beast_crc32 (checksum, buffer, (unsigned int) bytesRead);
target.write (buffer, (size_t) bytesRead);
}
return true;
}
void writeFlagsAndSizes (OutputStream& target) const
{
target.writeShort (10); // version needed
target.writeShort (0); // flags
target.writeShort (compressionLevel > 0 ? (short) 8 : (short) 0);
writeTimeAndDate (target);
target.writeInt ((int) checksum);
target.writeInt (compressedSize);
target.writeInt ((int) file.getSize());
target.writeShort ((short) storedPathname.toUTF8().sizeInBytes() - 1);
target.writeShort (0); // extra field length
}
};
//=============================================================================
ZipFile::Builder::Builder() {}
ZipFile::Builder::~Builder() {}
void ZipFile::Builder::addFile (const File& fileToAdd, const int compressionLevel, const String& storedPathName)
{
items.add (new Item (fileToAdd, compressionLevel, storedPathName));
}
bool ZipFile::Builder::writeToStream (OutputStream& target, double* const progress) const
{
const int64 fileStart = target.getPosition();
for (int i = 0; i < items.size(); ++i)
{
if (progress != nullptr)
*progress = (i + 0.5) / items.size();
if (! items.getUnchecked (i)->writeData (target, fileStart))
return false;
}
const int64 directoryStart = target.getPosition();
for (int i = 0; i < items.size(); ++i)
if (! items.getUnchecked (i)->writeDirectoryEntry (target))
return false;
const int64 directoryEnd = target.getPosition();
target.writeInt (0x06054b50);
target.writeShort (0);
target.writeShort (0);
target.writeShort ((short) items.size());
target.writeShort ((short) items.size());
target.writeInt ((int) (directoryEnd - directoryStart));
target.writeInt ((int) (directoryStart - fileStart));
target.writeShort (0);
if (progress != nullptr)
*progress = 1.0;
return true;
}
} // namespace beast

View File

@@ -1,244 +0,0 @@
/*
==============================================================================
This file is part of the beast_core module of the BEAST library.
Copyright (c) 2013 - Raw Material Software Ltd.
Permission to use, copy, modify, and/or distribute this software for any purpose with
or without fee is hereby granted, provided that the above copyright notice and this
permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
------------------------------------------------------------------------------
NOTE! This permissive ISC license applies ONLY to files within the beast_core module!
All other BEAST modules are covered by a dual GPL/commercial license, so if you are
using any other modules, be sure to check that you also comply with their license.
For more details, visit www.beast.com
==============================================================================
*/
#ifndef BEAST_ZIPFILE_H_INCLUDED
#define BEAST_ZIPFILE_H_INCLUDED
namespace beast
{
//==============================================================================
/**
Decodes a ZIP file from a stream.
This can enumerate the items in a ZIP file and can create suitable stream objects
to read each one.
*/
class BEAST_API ZipFile : LeakChecked <ZipFile>, public Uncopyable
{
public:
/** Creates a ZipFile based for a file. */
explicit ZipFile (const File& file);
//==============================================================================
/** Creates a ZipFile for a given stream.
@param inputStream the stream to read from
@param deleteStreamWhenDestroyed if set to true, the object passed-in
will be deleted when this ZipFile object is deleted
*/
ZipFile (InputStream* inputStream, bool deleteStreamWhenDestroyed);
/** Creates a ZipFile for a given stream.
The stream will not be owned or deleted by this class - if you want the ZipFile to
manage the stream's lifetime, use the other constructor.
*/
explicit ZipFile (InputStream& inputStream);
/** Creates a ZipFile for an input source.
The inputSource object will be owned by the zip file, which will delete
it later when not needed.
*/
explicit ZipFile (InputSource* inputSource);
/** Destructor. */
~ZipFile();
//==============================================================================
/**
Contains information about one of the entries in a ZipFile.
@see ZipFile::getEntry
*/
struct ZipEntry
{
/** The name of the file, which may also include a partial pathname. */
String filename;
/** The file's original size. */
unsigned int uncompressedSize;
/** The last time the file was modified. */
Time fileTime;
};
//==============================================================================
/** Returns the number of items in the zip file. */
int getNumEntries() const noexcept;
/** Returns a structure that describes one of the entries in the zip file.
This may return zero if the index is out of range.
@see ZipFile::ZipEntry
*/
const ZipEntry* getEntry (int index) const noexcept;
/** Returns the index of the first entry with a given filename.
This uses a case-sensitive comparison to look for a filename in the
list of entries. It might return -1 if no match is found.
@see ZipFile::ZipEntry
*/
int getIndexOfFileName (const String& fileName) const noexcept;
/** Returns a structure that describes one of the entries in the zip file.
This uses a case-sensitive comparison to look for a filename in the
list of entries. It might return 0 if no match is found.
@see ZipFile::ZipEntry
*/
const ZipEntry* getEntry (const String& fileName) const noexcept;
/** Sorts the list of entries, based on the filename.
*/
void sortEntriesByFilename();
//==============================================================================
/** Creates a stream that can read from one of the zip file's entries.
The stream that is returned must be deleted by the caller (and
zero might be returned if a stream can't be opened for some reason).
The stream must not be used after the ZipFile object that created
has been deleted.
*/
InputStream* createStreamForEntry (int index);
/** Creates a stream that can read from one of the zip file's entries.
The stream that is returned must be deleted by the caller (and
zero might be returned if a stream can't be opened for some reason).
The stream must not be used after the ZipFile object that created
has been deleted.
*/
InputStream* createStreamForEntry (const ZipEntry& entry);
//==============================================================================
/** Uncompresses all of the files in the zip file.
This will expand all the entries into a target directory. The relative
paths of the entries are used.
@param targetDirectory the root folder to uncompress to
@param shouldOverwriteFiles whether to overwrite existing files with similarly-named ones
@returns success if the file is successfully unzipped
*/
Result uncompressTo (const File& targetDirectory,
bool shouldOverwriteFiles = true);
/** Uncompresses one of the entries from the zip file.
This will expand the entry and write it in a target directory. The entry's path is used to
determine which subfolder of the target should contain the new file.
@param index the index of the entry to uncompress - this must be a valid index
between 0 and (getNumEntries() - 1).
@param targetDirectory the root folder to uncompress into
@param shouldOverwriteFiles whether to overwrite existing files with similarly-named ones
@returns success if all the files are successfully unzipped
*/
Result uncompressEntry (int index,
const File& targetDirectory,
bool shouldOverwriteFiles = true);
//==============================================================================
/** Used to create a new zip file.
Create a ZipFile::Builder object, and call its addFile() method to add some files,
then you can write it to a stream with write().
Currently this just stores the files with no compression.. That will be added
soon!
*/
class Builder : LeakChecked <Builder>, public Uncopyable
{
public:
Builder();
~Builder();
/** Adds a file while should be added to the archive.
The file isn't read immediately, all the files will be read later when the writeToStream()
method is called.
The compressionLevel can be between 0 (no compression), and 9 (maximum compression).
If the storedPathName parameter is specified, you can customise the partial pathname that
will be stored for this file.
*/
void addFile (const File& fileToAdd, int compressionLevel,
const String& storedPathName = String::empty);
/** Generates the zip file, writing it to the specified stream.
If the progress parameter is non-null, it will be updated with an approximate
progress status between 0 and 1.0
*/
bool writeToStream (OutputStream& target, double* progress) const;
//==============================================================================
private:
class Item;
friend class OwnedArray<Item>;
OwnedArray<Item> items;
};
private:
//==============================================================================
class ZipInputStream;
class ZipEntryHolder;
friend class ZipInputStream;
friend class ZipEntryHolder;
OwnedArray <ZipEntryHolder> entries;
CriticalSection lock;
InputStream* inputStream;
ScopedPointer <InputStream> streamToDelete;
ScopedPointer <InputSource> inputSource;
#if BEAST_DEBUG
struct OpenStreamCounter
{
OpenStreamCounter() : numOpenStreams (0) {}
~OpenStreamCounter();
int numOpenStreams;
};
OpenStreamCounter streamCounter;
#endif
void init();
};
} // namespace beast
#endif // BEAST_ZIPFILE_H_INCLUDED

View File

@@ -1,125 +0,0 @@
ZLIB DATA COMPRESSION LIBRARY
zlib 1.2.3 is a general purpose data compression library. All the code is
thread safe. The data format used by the zlib library is described by RFCs
(Request for Comments) 1950 to 1952 in the files
http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
and rfc1952.txt (gzip format). These documents are also available in other
formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
All functions of the compression library are documented in the file zlib.h
(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example
of the library is given in the file example.c which also tests that the library
is working correctly. Another example is given in the file minigzip.c. The
compression library itself is composed of all source files except example.c and
minigzip.c.
To compile all files and run the test program, follow the instructions given at
the top of Makefile. In short "make test; make install" should work for most
machines. For Unix: "./configure; make test; make install". For MSDOS, use one
of the special makefiles such as Makefile.msc. For VMS, use make_vms.com.
Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
<info@winimage.com> for the Windows DLL version. The zlib home page is
http://www.zlib.org or http://www.gzip.org/zlib/ Before reporting a problem,
please check this site to verify that you have the latest version of zlib;
otherwise get the latest version and check whether the problem still exists or
not.
PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html before asking
for help.
Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
issue of Dr. Dobb's Journal; a copy of the article is available in
http://dogma.net/markn/articles/zlibtool/zlibtool.htm
The changes made in version 1.2.3 are documented in the file ChangeLog.
Unsupported third party contributions are provided in directory "contrib".
A Java implementation of zlib is available in the Java Development Kit
http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/package-summary.html
See the zlib home page http://www.zlib.org for details.
A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is in the
CPAN (Comprehensive Perl Archive Network) sites
http://www.cpan.org/modules/by-module/Compress/
A Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is
available in Python 1.5 and later versions, see
http://www.python.org/doc/lib/module-zlib.html
A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com> is
availlable at http://www.oche.de/~akupries/soft/trf/trf_zip.html
An experimental package to read and write files in .zip format, written on top
of zlib by Gilles Vollant <info@winimage.com>, is available in the
contrib/minizip directory of zlib.
Notes for some targets:
- For Windows DLL versions, please see win32/DLL_FAQ.txt
- For 64-bit Irix, deflate.c must be compiled without any optimization. With
-O, one libpng test fails. The test works in 32 bit mode (with the -n32
compiler flag). The compiler bug has been reported to SGI.
- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works
when compiled with cc.
- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is
necessary to get gzprintf working correctly. This is done by configure.
- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
other compilers. Use "make test" to check your compiler.
- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
- For PalmOs, see http://palmzlib.sourceforge.net/
- When building a shared, i.e. dynamic library on Mac OS X, the library must be
installed before testing (do "make install" before "make test"), since the
library location is specified in the library.
Acknowledgments:
The deflate format used by zlib was defined by Phil Katz. The deflate
and zlib specifications were written by L. Peter Deutsch. Thanks to all the
people who reported problems and suggested various improvements in zlib;
they are too numerous to cite here.
Copyright notice:
(C) 1995-2004 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jean-loup Gailly Mark Adler
jloup@gzip.org madler@alumni.caltech.edu
If you use the zlib library in a product, we would appreciate *not*
receiving lengthy legal documents to sign. The sources are provided
for free but without warranty of any kind. The library has been
entirely written by Jean-loup Gailly and Mark Adler; it does not
include third-party code.
If you redistribute modified sources, we would appreciate that you include
in the file ChangeLog history information documenting your changes. Please
read the FAQ for more information on the distribution of modified source
versions.

View File

@@ -1,143 +0,0 @@
/* adler32.c -- compute the Adler-32 checksum of a data stream
* Copyright (C) 1995-2004 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id: adler32.c,v 1.1 2007/06/07 17:54:37 jules_rms Exp $ */
#define ZLIB_INTERNAL
#include "zlib.h"
#define BASE 65521UL /* largest prime smaller than 65536 */
#define NMAX 5552
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
#define DO16(buf) DO8(buf,0); DO8(buf,8);
/* use NO_DIVIDE if your processor does not do division in hardware */
#ifdef NO_DIVIDE
# define MOD(a) \
do { \
if (a >= (BASE << 16)) a -= (BASE << 16); \
if (a >= (BASE << 15)) a -= (BASE << 15); \
if (a >= (BASE << 14)) a -= (BASE << 14); \
if (a >= (BASE << 13)) a -= (BASE << 13); \
if (a >= (BASE << 12)) a -= (BASE << 12); \
if (a >= (BASE << 11)) a -= (BASE << 11); \
if (a >= (BASE << 10)) a -= (BASE << 10); \
if (a >= (BASE << 9)) a -= (BASE << 9); \
if (a >= (BASE << 8)) a -= (BASE << 8); \
if (a >= (BASE << 7)) a -= (BASE << 7); \
if (a >= (BASE << 6)) a -= (BASE << 6); \
if (a >= (BASE << 5)) a -= (BASE << 5); \
if (a >= (BASE << 4)) a -= (BASE << 4); \
if (a >= (BASE << 3)) a -= (BASE << 3); \
if (a >= (BASE << 2)) a -= (BASE << 2); \
if (a >= (BASE << 1)) a -= (BASE << 1); \
if (a >= BASE) a -= BASE; \
} while (0)
# define MOD4(a) \
do { \
if (a >= (BASE << 4)) a -= (BASE << 4); \
if (a >= (BASE << 3)) a -= (BASE << 3); \
if (a >= (BASE << 2)) a -= (BASE << 2); \
if (a >= (BASE << 1)) a -= (BASE << 1); \
if (a >= BASE) a -= BASE; \
} while (0)
#else
# define MOD(a) a %= BASE
# define MOD4(a) a %= BASE
#endif
/* ========================================================================= */
uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len)
{
unsigned long sum2;
unsigned n;
/* split Adler-32 into component sums */
sum2 = (adler >> 16) & 0xffff;
adler &= 0xffff;
/* in case user likes doing a byte at a time, keep it fast */
if (len == 1) {
adler += buf[0];
if (adler >= BASE)
adler -= BASE;
sum2 += adler;
if (sum2 >= BASE)
sum2 -= BASE;
return adler | (sum2 << 16);
}
/* initial Adler-32 value (deferred check for len == 1 speed) */
if (buf == Z_NULL)
return 1L;
/* in case short lengths are provided, keep it somewhat fast */
if (len < 16) {
while (len--) {
adler += *buf++;
sum2 += adler;
}
if (adler >= BASE)
adler -= BASE;
MOD4(sum2); /* only added so many BASE's */
return adler | (sum2 << 16);
}
/* do length NMAX blocks -- requires just one modulo operation */
while (len >= NMAX) {
len -= NMAX;
n = NMAX / 16; /* NMAX is divisible by 16 */
do {
DO16(buf); /* 16 sums unrolled */
buf += 16;
} while (--n);
MOD(adler);
MOD(sum2);
}
/* do remaining bytes (less than NMAX, still just one modulo) */
if (len) { /* avoid modulos if none remaining */
while (len >= 16) {
len -= 16;
DO16(buf);
buf += 16;
}
while (len--) {
adler += *buf++;
sum2 += adler;
}
MOD(adler);
MOD(sum2);
}
/* return recombined sums */
return adler | (sum2 << 16);
}
/* ========================================================================= */
uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, z_off_t len2)
{
unsigned long sum1;
unsigned long sum2;
unsigned rem;
/* the derivation of this formula is left as an exercise for the reader */
rem = (unsigned)(len2 % BASE);
sum1 = adler1 & 0xffff;
sum2 = rem * sum1;
MOD(sum2);
sum1 += (adler2 & 0xffff) + BASE - 1;
sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
if (sum1 > BASE) sum1 -= BASE;
if (sum1 > BASE) sum1 -= BASE;
if (sum2 > (BASE << 1)) sum2 -= (BASE << 1);
if (sum2 > BASE) sum2 -= BASE;
return sum1 | (sum2 << 16);
}

View File

@@ -1,70 +0,0 @@
/* compress.c -- compress a memory buffer
* Copyright (C) 1995-2003 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id: compress.c,v 1.1 2007/06/07 17:54:37 jules_rms Exp $ */
#define ZLIB_INTERNAL
#include "zlib.h"
/* ===========================================================================
Compresses the source buffer into the destination buffer. The level
parameter has the same meaning as in deflateInit. sourceLen is the byte
length of the source buffer. Upon entry, destLen is the total size of the
destination buffer, which must be at least 0.1% larger than sourceLen plus
12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
memory, Z_BUF_ERROR if there was not enough room in the output buffer,
Z_STREAM_ERROR if the level parameter is invalid.
*/
int ZEXPORT compress2 (Bytef *dest, uLongf *destLen, const Bytef *source,
uLong sourceLen, int level)
{
z_stream stream;
int err;
stream.next_in = (Bytef*)source;
stream.avail_in = (uInt)sourceLen;
#ifdef MAXSEG_64K
/* Check for source > 64K on 16-bit machine: */
if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
#endif
stream.next_out = dest;
stream.avail_out = (uInt)*destLen;
if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
stream.zalloc = (alloc_func)0;
stream.zfree = (free_func)0;
stream.opaque = (voidpf)0;
err = deflateInit(&stream, level);
if (err != Z_OK) return err;
err = deflate(&stream, Z_FINISH);
if (err != Z_STREAM_END) {
deflateEnd(&stream);
return err == Z_OK ? Z_BUF_ERROR : err;
}
*destLen = stream.total_out;
err = deflateEnd(&stream);
return err;
}
/* ===========================================================================
*/
int ZEXPORT compress (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)
{
return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
}
/* ===========================================================================
If the default memLevel or windowBits for deflateInit() is changed, then
this function needs to be updated.
*/
uLong ZEXPORT compressBound (uLong sourceLen)
{
return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
}

View File

@@ -1,407 +0,0 @@
/* crc32.c -- compute the CRC-32 of a data stream
* Copyright (C) 1995-2005 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*
* Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
* CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
* tables for updating the shift register in one step with three exclusive-ors
* instead of four steps with four exclusive-ors. This results in about a
* factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
*/
/* @(#) $Id: crc32.c,v 1.1 2007/06/07 17:54:37 jules_rms Exp $ */
/*
Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
protection on the static variables used to control the first-use generation
of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
first call get_crc_table() to initialize the tables before allowing more than
one thread to use crc32().
*/
#ifdef MAKECRCH
# include <stdio.h>
# ifndef DYNAMIC_CRC_TABLE
# define DYNAMIC_CRC_TABLE
# endif /* !DYNAMIC_CRC_TABLE */
#endif /* MAKECRCH */
#include "zutil.h" /* for STDC and FAR definitions */
#define local static
/* Find a four-byte integer type for crc32_little() and crc32_big(). */
#ifndef NOBYFOUR
# ifdef STDC /* need ANSI C limits.h to determine sizes */
# include <limits.h>
# define BYFOUR
# if (UINT_MAX == 0xffffffffUL)
typedef unsigned int u4;
# else
# if (ULONG_MAX == 0xffffffffUL)
typedef unsigned long u4;
# else
# if (USHRT_MAX == 0xffffffffUL)
typedef unsigned short u4;
# else
# undef BYFOUR /* can't find a four-byte integer type! */
# endif
# endif
# endif
# endif /* STDC */
#endif /* !NOBYFOUR */
/* Definitions for doing the crc four data bytes at a time. */
#ifdef BYFOUR
# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
(((w)&0xff00)<<8)+(((w)&0xff)<<24))
local unsigned long crc32_little OF((unsigned long,
const unsigned char FAR *, unsigned));
local unsigned long crc32_big OF((unsigned long,
const unsigned char FAR *, unsigned));
# define TBLS 8
#else
# define TBLS 1
#endif /* BYFOUR */
/* Local functions for crc concatenation */
local unsigned long gf2_matrix_times OF((unsigned long *mat,
unsigned long vec));
local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
#ifdef DYNAMIC_CRC_TABLE
local volatile int crc_table_empty = 1;
local unsigned long FAR crc_table[TBLS][256];
local void make_crc_table OF((void));
#ifdef MAKECRCH
local void write_table OF((FILE *, const unsigned long FAR *));
#endif /* MAKECRCH */
/*
Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
Polynomials over GF(2) are represented in binary, one bit per coefficient,
with the lowest powers in the most significant bit. Then adding polynomials
is just exclusive-or, and multiplying a polynomial by x is a right shift by
one. If we call the above polynomial p, and represent a byte as the
polynomial q, also with the lowest power in the most significant bit (so the
byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
where a mod b means the remainder after dividing a by b.
This calculation is done using the shift-register method of multiplying and
taking the remainder. The register is initialized to zero, and for each
incoming bit, x^32 is added mod p to the register if the bit is a one (where
x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
x (which is shifting right by one and adding x^32 mod p if the bit shifted
out is a one). We start with the highest power (least significant bit) of
q and repeat for all eight bits of q.
The first table is simply the CRC of all possible eight bit values. This is
all the information needed to generate CRCs on data a byte at a time for all
combinations of CRC register values and incoming bytes. The remaining tables
allow for word-at-a-time CRC calculation for both big-endian and little-
endian machines, where a word is four bytes.
*/
local void make_crc_table()
{
unsigned long c;
int n, k;
unsigned long poly; /* polynomial exclusive-or pattern */
/* terms of polynomial defining this crc (except x^32): */
static volatile int first = 1; /* flag to limit concurrent making */
static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
/* See if another task is already doing this (not thread-safe, but better
than nothing -- significantly reduces duration of vulnerability in
case the advice about DYNAMIC_CRC_TABLE is ignored) */
if (first) {
first = 0;
/* make exclusive-or pattern from polynomial (0xedb88320UL) */
poly = 0UL;
for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
poly |= 1UL << (31 - p[n]);
/* generate a crc for every 8-bit value */
for (n = 0; n < 256; n++) {
c = (unsigned long)n;
for (k = 0; k < 8; k++)
c = c & 1 ? poly ^ (c >> 1) : c >> 1;
crc_table[0][n] = c;
}
#ifdef BYFOUR
/* generate crc for each value followed by one, two, and three zeros,
and then the byte reversal of those as well as the first table */
for (n = 0; n < 256; n++) {
c = crc_table[0][n];
crc_table[4][n] = REV(c);
for (k = 1; k < 4; k++) {
c = crc_table[0][c & 0xff] ^ (c >> 8);
crc_table[k][n] = c;
crc_table[k + 4][n] = REV(c);
}
}
#endif /* BYFOUR */
crc_table_empty = 0;
}
else { /* not first */
/* wait for the other guy to finish (not efficient, but rare) */
while (crc_table_empty)
;
}
#ifdef MAKECRCH
/* write out CRC tables to crc32.h */
{
FILE *out;
out = fopen("crc32.h", "w");
if (out == NULL) return;
fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
fprintf(out, "local const unsigned long FAR ");
fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
write_table(out, crc_table[0]);
# ifdef BYFOUR
fprintf(out, "#ifdef BYFOUR\n");
for (k = 1; k < 8; k++) {
fprintf(out, " },\n {\n");
write_table(out, crc_table[k]);
}
fprintf(out, "#endif\n");
# endif /* BYFOUR */
fprintf(out, " }\n};\n");
fclose(out);
}
#endif /* MAKECRCH */
}
#ifdef MAKECRCH
local void write_table(out, table)
FILE *out;
const unsigned long FAR *table;
{
int n;
for (n = 0; n < 256; n++)
fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
}
#endif /* MAKECRCH */
#else /* !DYNAMIC_CRC_TABLE */
/* ========================================================================
* Tables of CRC-32s of all single-byte values, made by make_crc_table().
*/
#include "crc32.h"
#endif /* DYNAMIC_CRC_TABLE */
/* =========================================================================
* This function can be used by asm versions of crc32()
*/
const unsigned long FAR * ZEXPORT get_crc_table()
{
#ifdef DYNAMIC_CRC_TABLE
if (crc_table_empty)
make_crc_table();
#endif /* DYNAMIC_CRC_TABLE */
return (const unsigned long FAR *)crc_table;
}
/* ========================================================================= */
#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
/* ========================================================================= */
unsigned long ZEXPORT crc32 (unsigned long crc, const unsigned char FAR *buf, unsigned len)
{
if (buf == Z_NULL) return 0UL;
#ifdef DYNAMIC_CRC_TABLE
if (crc_table_empty)
make_crc_table();
#endif /* DYNAMIC_CRC_TABLE */
#ifdef BYFOUR
if (sizeof(void *) == sizeof(ptrdiff_t)) {
u4 endian;
endian = 1;
if (*((unsigned char *)(&endian)))
return crc32_little(crc, buf, len);
else
return crc32_big(crc, buf, len);
}
#endif /* BYFOUR */
crc = crc ^ 0xffffffffUL;
while (len >= 8) {
DO8;
len -= 8;
}
if (len) do {
DO1;
} while (--len);
return crc ^ 0xffffffffUL;
}
#ifdef BYFOUR
/* ========================================================================= */
#define DOLIT4 c ^= *buf4++; \
c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
/* ========================================================================= */
local unsigned long crc32_little(unsigned long crc, const unsigned char FAR *buf, unsigned len)
{
register u4 c;
register const u4 FAR *buf4;
c = (u4)crc;
c = ~c;
while (len && ((ptrdiff_t)buf & 3)) {
c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
len--;
}
buf4 = (const u4 FAR *)(const void FAR *)buf;
while (len >= 32) {
DOLIT32;
len -= 32;
}
while (len >= 4) {
DOLIT4;
len -= 4;
}
buf = (const unsigned char FAR *)buf4;
if (len) do {
c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
} while (--len);
c = ~c;
return (unsigned long)c;
}
/* ========================================================================= */
#define DOBIG4 c ^= *++buf4; \
c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
/* ========================================================================= */
local unsigned long crc32_big (unsigned long crc, const unsigned char FAR *buf, unsigned len)
{
register u4 c;
register const u4 FAR *buf4;
c = REV((u4)crc);
c = ~c;
while (len && ((ptrdiff_t)buf & 3)) {
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
len--;
}
buf4 = (const u4 FAR *)(const void FAR *)buf;
buf4--;
while (len >= 32) {
DOBIG32;
len -= 32;
}
while (len >= 4) {
DOBIG4;
len -= 4;
}
buf4++;
buf = (const unsigned char FAR *)buf4;
if (len) do {
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
} while (--len);
c = ~c;
return (unsigned long)(REV(c));
}
#endif /* BYFOUR */
#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
/* ========================================================================= */
local unsigned long gf2_matrix_times (unsigned long *mat, unsigned long vec)
{
unsigned long sum;
sum = 0;
while (vec) {
if (vec & 1)
sum ^= *mat;
vec >>= 1;
mat++;
}
return sum;
}
/* ========================================================================= */
local void gf2_matrix_square (unsigned long *square, unsigned long *mat)
{
int n;
for (n = 0; n < GF2_DIM; n++)
square[n] = gf2_matrix_times(mat, mat[n]);
}
/* ========================================================================= */
uLong ZEXPORT crc32_combine (uLong crc1, uLong crc2, z_off_t len2)
{
int n;
unsigned long row;
unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
/* degenerate case */
if (len2 == 0)
return crc1;
/* put operator for one zero bit in odd */
odd[0] = 0xedb88320L; /* CRC-32 polynomial */
row = 1;
for (n = 1; n < GF2_DIM; n++) {
odd[n] = row;
row <<= 1;
}
/* put operator for two zero bits in even */
gf2_matrix_square(even, odd);
/* put operator for four zero bits in odd */
gf2_matrix_square(odd, even);
/* apply len2 zeros to crc1 (first square will put the operator for one
zero byte, eight zero bits, in even) */
do {
/* apply zeros operator for this bit of len2 */
gf2_matrix_square(even, odd);
if (len2 & 1)
crc1 = gf2_matrix_times(even, crc1);
len2 >>= 1;
/* if no more bits set, then done */
if (len2 == 0)
break;
/* another iteration of the loop with odd and even swapped */
gf2_matrix_square(odd, even);
if (len2 & 1)
crc1 = gf2_matrix_times(odd, crc1);
len2 >>= 1;
/* if no more bits set, then done */
} while (len2 != 0);
/* return combined crc */
crc1 ^= crc2;
return crc1;
}

View File

@@ -1,441 +0,0 @@
/* crc32.h -- tables for rapid CRC calculation
* Generated automatically by crc32.c
*/
local const unsigned long FAR crc_table[TBLS][256] =
{
{
0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
0x2d02ef8dUL
#ifdef BYFOUR
},
{
0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
0x9324fd72UL
},
{
0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
0xbe9834edUL
},
{
0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
0xde0506f1UL
},
{
0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
0x8def022dUL
},
{
0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
0x72fd2493UL
},
{
0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
0xed3498beUL
},
{
0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
0xf10605deUL
#endif
}
};

File diff suppressed because it is too large Load Diff

View File

@@ -1,333 +0,0 @@
/* deflate.h -- internal compression state
* Copyright (C) 1995-2004 Jean-loup Gailly
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
/* @(#) $Id: deflate.h,v 1.1 2007/06/07 17:54:37 jules_rms Exp $ */
#ifndef DEFLATE_H
#define DEFLATE_H
#include "zutil.h"
/* define NO_GZIP when compiling if you want to disable gzip header and
trailer creation by deflate(). NO_GZIP would be used to avoid linking in
the crc code when it is not needed. For shared libraries, gzip encoding
should be left enabled. */
#ifndef NO_GZIP
# define GZIP
#endif
#define NO_DUMMY_DECL
/* ===========================================================================
* Internal compression state.
*/
#define LENGTH_CODES 29
/* number of length codes, not counting the special END_BLOCK code */
#define LITERALS 256
/* number of literal bytes 0..255 */
#define L_CODES (LITERALS+1+LENGTH_CODES)
/* number of Literal or Length codes, including the END_BLOCK code */
#define D_CODES 30
/* number of distance codes */
#define BL_CODES 19
/* number of codes used to transfer the bit lengths */
#define HEAP_SIZE (2*L_CODES+1)
/* maximum heap size */
#define MAX_BITS 15
/* All codes must not exceed MAX_BITS bits */
#define INIT_STATE 42
#define EXTRA_STATE 69
#define NAME_STATE 73
#define COMMENT_STATE 91
#define HCRC_STATE 103
#define BUSY_STATE 113
#define FINISH_STATE 666
/* Stream status */
/* Data structure describing a single value and its code string. */
typedef struct ct_data_s {
union {
ush freq; /* frequency count */
ush code; /* bit string */
} fc;
union {
ush dad; /* father node in Huffman tree */
ush len; /* length of bit string */
} dl;
} FAR ct_data;
#define Freq fc.freq
#define Code fc.code
#define Dad dl.dad
#define Len dl.len
typedef struct static_tree_desc_s static_tree_desc;
typedef struct tree_desc_s {
ct_data *dyn_tree; /* the dynamic tree */
int max_code; /* largest code with non zero frequency */
static_tree_desc *stat_desc; /* the corresponding static tree */
} FAR tree_desc;
typedef ush Pos;
typedef Pos FAR Posf;
typedef unsigned IPos;
/* A Pos is an index in the character window. We use short instead of int to
* save space in the various tables. IPos is used only for parameter passing.
*/
typedef struct internal_state {
z_streamp strm; /* pointer back to this zlib stream */
int status; /* as the name implies */
Bytef *pending_buf; /* output still pending */
ulg pending_buf_size; /* size of pending_buf */
Bytef *pending_out; /* next pending byte to output to the stream */
uInt pending; /* nb of bytes in the pending buffer */
int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
gz_headerp gzhead; /* gzip header information to write */
uInt gzindex; /* where in extra, name, or comment */
Byte method; /* STORED (for zip only) or DEFLATED */
int last_flush; /* value of flush param for previous deflate call */
/* used by deflate.c: */
uInt w_size; /* LZ77 window size (32K by default) */
uInt w_bits; /* log2(w_size) (8..16) */
uInt w_mask; /* w_size - 1 */
Bytef *window;
/* Sliding window. Input bytes are read into the second half of the window,
* and move to the first half later to keep a dictionary of at least wSize
* bytes. With this organization, matches are limited to a distance of
* wSize-MAX_MATCH bytes, but this ensures that IO is always
* performed with a length multiple of the block size. Also, it limits
* the window size to 64K, which is quite useful on MSDOS.
* To do: use the user input buffer as sliding window.
*/
ulg window_size;
/* Actual size of window: 2*wSize, except when the user input buffer
* is directly used as sliding window.
*/
Posf *prev;
/* Link to older string with same hash index. To limit the size of this
* array to 64K, this link is maintained only for the last 32K strings.
* An index in this array is thus a window index modulo 32K.
*/
Posf *head; /* Heads of the hash chains or NIL. */
uInt ins_h; /* hash index of string to be inserted */
uInt hash_size; /* number of elements in hash table */
uInt hash_bits; /* log2(hash_size) */
uInt hash_mask; /* hash_size-1 */
uInt hash_shift;
/* Number of bits by which ins_h must be shifted at each input
* step. It must be such that after MIN_MATCH steps, the oldest
* byte no longer takes part in the hash key, that is:
* hash_shift * MIN_MATCH >= hash_bits
*/
long block_start;
/* Window position at the beginning of the current output block. Gets
* negative when the window is moved backwards.
*/
uInt match_length; /* length of best match */
IPos prev_match; /* previous match */
int match_available; /* set if previous match exists */
uInt strstart; /* start of string to insert */
uInt match_start; /* start of matching string */
uInt lookahead; /* number of valid bytes ahead in window */
uInt prev_length;
/* Length of the best match at previous step. Matches not greater than this
* are discarded. This is used in the lazy match evaluation.
*/
uInt max_chain_length;
/* To speed up deflation, hash chains are never searched beyond this
* length. A higher limit improves compression ratio but degrades the
* speed.
*/
uInt max_lazy_match;
/* Attempt to find a better match only when the current match is strictly
* smaller than this value. This mechanism is used only for compression
* levels >= 4.
*/
# define max_insert_length max_lazy_match
/* Insert new strings in the hash table only if the match length is not
* greater than this length. This saves time but degrades compression.
* max_insert_length is used only for compression levels <= 3.
*/
int level; /* compression level (1..9) */
int strategy; /* favor or force Huffman coding*/
uInt good_match;
/* Use a faster search when the previous match is longer than this */
int nice_match; /* Stop searching when current match exceeds this */
/* used by trees.c: */
/* Didn't use ct_data typedef below to supress compiler warning */
struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
struct tree_desc_s l_desc; /* desc. for literal tree */
struct tree_desc_s d_desc; /* desc. for distance tree */
struct tree_desc_s bl_desc; /* desc. for bit length tree */
ush bl_count[MAX_BITS+1];
/* number of codes at each bit length for an optimal tree */
int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
int heap_len; /* number of elements in the heap */
int heap_max; /* element of largest frequency */
/* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
* The same heap array is used to build all trees.
*/
uch depth[2*L_CODES+1];
/* Depth of each subtree used as tie breaker for trees of equal frequency
*/
uchf *l_buf; /* buffer for literals or lengths */
uInt lit_bufsize;
/* Size of match buffer for literals/lengths. There are 4 reasons for
* limiting lit_bufsize to 64K:
* - frequencies can be kept in 16 bit counters
* - if compression is not successful for the first block, all input
* data is still in the window so we can still emit a stored block even
* when input comes from standard input. (This can also be done for
* all blocks if lit_bufsize is not greater than 32K.)
* - if compression is not successful for a file smaller than 64K, we can
* even emit a stored file instead of a stored block (saving 5 bytes).
* This is applicable only for zip (not gzip or zlib).
* - creating new Huffman trees less frequently may not provide fast
* adaptation to changes in the input data statistics. (Take for
* example a binary file with poorly compressible code followed by
* a highly compressible string table.) Smaller buffer sizes give
* fast adaptation but have of course the overhead of transmitting
* trees more frequently.
* - I can't count above 4
*/
uInt last_lit; /* running index in l_buf */
ushf *d_buf;
/* Buffer for distances. To simplify the code, d_buf and l_buf have
* the same number of elements. To use different lengths, an extra flag
* array would be necessary.
*/
ulg opt_len; /* bit length of current block with optimal trees */
ulg static_len; /* bit length of current block with static trees */
uInt matches; /* number of string matches in current block */
int last_eob_len; /* bit length of EOB code for last block */
#ifdef DEBUG
ulg compressed_len; /* total bit length of compressed file mod 2^32 */
ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
#endif
ush bi_buf;
/* Output buffer. bits are inserted starting at the bottom (least
* significant bits).
*/
int bi_valid;
/* Number of valid bits in bi_buf. All bits above the last valid bit
* are always zero.
*/
} FAR deflate_state;
/* Output a byte on the stream.
* IN assertion: there is enough room in pending_buf.
*/
#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
/* Minimum amount of lookahead, except at the end of the input file.
* See deflate.c for comments about the MIN_MATCH+1.
*/
#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
/* In order to simplify the code, particularly on 16 bit machines, match
* distances are limited to MAX_DIST instead of WSIZE.
*/
/* in trees.c */
void _tr_init OF((deflate_state *s));
int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
int eof));
void _tr_align OF((deflate_state *s));
void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
int eof));
#define d_code(dist) \
((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
/* Mapping from a distance to a distance code. dist is the distance - 1 and
* must not have side effects. _dist_code[256] and _dist_code[257] are never
* used.
*/
#ifndef DEBUG
/* Inline versions of _tr_tally for speed: */
#if defined(GEN_TREES_H) || !defined(STDC)
extern uch _length_code[];
extern uch _dist_code[];
#else
extern const uch _length_code[];
extern const uch _dist_code[];
#endif
# define _tr_tally_lit(s, c, flush) \
{ uch cc = (c); \
s->d_buf[s->last_lit] = 0; \
s->l_buf[s->last_lit++] = cc; \
s->dyn_ltree[cc].Freq++; \
flush = (s->last_lit == s->lit_bufsize-1); \
}
# define _tr_tally_dist(s, distance, length, flush) \
{ uch len = (length); \
ush dist = (distance); \
s->d_buf[s->last_lit] = dist; \
s->l_buf[s->last_lit++] = len; \
dist--; \
s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
s->dyn_dtree[d_code(dist)].Freq++; \
flush = (s->last_lit == s->lit_bufsize-1); \
}
#else
# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
# define _tr_tally_dist(s, distance, length, flush) \
flush = _tr_tally(s, distance, length)
#endif
#endif /* DEFLATE_H */

View File

@@ -1,611 +0,0 @@
/* infback.c -- inflate using a call-back interface
* Copyright (C) 1995-2005 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/*
This code is largely copied from inflate.c. Normally either infback.o or
inflate.o would be linked into an application--not both. The interface
with inffast.c is retained so that optimized assembler-coded versions of
inflate_fast() can be used with either inflate.c or infback.c.
*/
#include "zutil.h"
#include "inftrees.h"
#include "inflate.h"
#include "inffast.h"
/* function prototypes */
local void fixedtables1 OF((struct inflate_state FAR *state));
/*
strm provides memory allocation functions in zalloc and zfree, or
Z_NULL to use the library memory allocation functions.
windowBits is in the range 8..15, and window is a user-supplied
window and output buffer that is 2**windowBits bytes.
*/
int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, unsigned char FAR *window, const char *version, int stream_size)
{
struct inflate_state FAR *state;
if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
stream_size != (int)(sizeof(z_stream)))
return Z_VERSION_ERROR;
if (strm == Z_NULL || window == Z_NULL ||
windowBits < 8 || windowBits > 15)
return Z_STREAM_ERROR;
strm->msg = Z_NULL; /* in case we return an error */
if (strm->zalloc == (alloc_func)0) {
strm->zalloc = zcalloc;
strm->opaque = (voidpf)0;
}
if (strm->zfree == (free_func)0) strm->zfree = zcfree;
state = (struct inflate_state FAR *)ZALLOC(strm, 1,
sizeof(struct inflate_state));
if (state == Z_NULL) return Z_MEM_ERROR;
Tracev((stderr, "inflate: allocated\n"));
strm->state = (struct internal_state FAR *)state;
state->dmax = 32768U;
state->wbits = windowBits;
state->wsize = 1U << windowBits;
state->window = window;
state->write = 0;
state->whave = 0;
return Z_OK;
}
/*
Return state with length and distance decoding tables and index sizes set to
fixed code decoding. Normally this returns fixed tables from inffixed.h.
If BUILDFIXED is defined, then instead this routine builds the tables the
first time it's called, and returns those tables the first time and
thereafter. This reduces the size of the code by about 2K bytes, in
exchange for a little execution time. However, BUILDFIXED should not be
used for threaded applications, since the rewriting of the tables and virgin
may not be thread-safe.
*/
local void fixedtables1 (struct inflate_state FAR *state)
{
#ifdef BUILDFIXED
static int virgin = 1;
static code *lenfix, *distfix;
static code fixed[544];
/* build fixed huffman tables if first call (may not be thread safe) */
if (virgin) {
unsigned sym, bits;
static code *next;
/* literal/length table */
sym = 0;
while (sym < 144) state->lens[sym++] = 8;
while (sym < 256) state->lens[sym++] = 9;
while (sym < 280) state->lens[sym++] = 7;
while (sym < 288) state->lens[sym++] = 8;
next = fixed;
lenfix = next;
bits = 9;
inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
/* distance table */
sym = 0;
while (sym < 32) state->lens[sym++] = 5;
distfix = next;
bits = 5;
inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
/* do this just once */
virgin = 0;
}
#else /* !BUILDFIXED */
# include "inffixed.h"
#endif /* BUILDFIXED */
state->lencode = lenfix;
state->lenbits = 9;
state->distcode = distfix;
state->distbits = 5;
}
/* Macros for inflateBack(): */
/* Load returned state from inflate_fast() */
#define LOAD() \
do { \
put = strm->next_out; \
left = strm->avail_out; \
next = strm->next_in; \
have = strm->avail_in; \
hold = state->hold; \
bits = state->bits; \
} while (0)
/* Set state from registers for inflate_fast() */
#define RESTORE() \
do { \
strm->next_out = put; \
strm->avail_out = left; \
strm->next_in = next; \
strm->avail_in = have; \
state->hold = hold; \
state->bits = bits; \
} while (0)
/* Clear the input bit accumulator */
#define INITBITS() \
do { \
hold = 0; \
bits = 0; \
} while (0)
/* Assure that some input is available. If input is requested, but denied,
then return a Z_BUF_ERROR from inflateBack(). */
#define PULL() \
do { \
if (have == 0) { \
have = in(in_desc, &next); \
if (have == 0) { \
next = Z_NULL; \
ret = Z_BUF_ERROR; \
goto inf_leave; \
} \
} \
} while (0)
/* Get a byte of input into the bit accumulator, or return from inflateBack()
with an error if there is no input available. */
#define PULLBYTE() \
do { \
PULL(); \
have--; \
hold += (unsigned long)(*next++) << bits; \
bits += 8; \
} while (0)
/* Assure that there are at least n bits in the bit accumulator. If there is
not enough available input to do that, then return from inflateBack() with
an error. */
#define NEEDBITS(n) \
do { \
while (bits < (unsigned)(n)) \
PULLBYTE(); \
} while (0)
/* Return the low n bits of the bit accumulator (n < 16) */
#define BITS(n) \
((unsigned)hold & ((1U << (n)) - 1))
/* Remove n bits from the bit accumulator */
#define DROPBITS(n) \
do { \
hold >>= (n); \
bits -= (unsigned)(n); \
} while (0)
/* Remove zero to seven bits as needed to go to a byte boundary */
#define BYTEBITS() \
do { \
hold >>= bits & 7; \
bits -= bits & 7; \
} while (0)
/* Assure that some output space is available, by writing out the window
if it's full. If the write fails, return from inflateBack() with a
Z_BUF_ERROR. */
#define ROOM() \
do { \
if (left == 0) { \
put = state->window; \
left = state->wsize; \
state->whave = left; \
if (out(out_desc, put, left)) { \
ret = Z_BUF_ERROR; \
goto inf_leave; \
} \
} \
} while (0)
/*
strm provides the memory allocation functions and window buffer on input,
and provides information on the unused input on return. For Z_DATA_ERROR
returns, strm will also provide an error message.
in() and out() are the call-back input and output functions. When
inflateBack() needs more input, it calls in(). When inflateBack() has
filled the window with output, or when it completes with data in the
window, it calls out() to write out the data. The application must not
change the provided input until in() is called again or inflateBack()
returns. The application must not change the window/output buffer until
inflateBack() returns.
in() and out() are called with a descriptor parameter provided in the
inflateBack() call. This parameter can be a structure that provides the
information required to do the read or write, as well as accumulated
information on the input and output such as totals and check values.
in() should return zero on failure. out() should return non-zero on
failure. If either in() or out() fails, than inflateBack() returns a
Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it
was in() or out() that caused in the error. Otherwise, inflateBack()
returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
error, or Z_MEM_ERROR if it could not allocate memory for the state.
inflateBack() can also return Z_STREAM_ERROR if the input parameters
are not correct, i.e. strm is Z_NULL or the state was not initialized.
*/
int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, out_func out, void FAR *out_desc)
{
struct inflate_state FAR *state;
unsigned char FAR *next; /* next input */
unsigned char FAR *put; /* next output */
unsigned have, left; /* available input and output */
unsigned long hold; /* bit buffer */
unsigned bits; /* bits in bit buffer */
unsigned copy; /* number of stored or match bytes to copy */
unsigned char FAR *from; /* where to copy match bytes from */
code thisx; /* current decoding table entry */
code last; /* parent table entry */
unsigned len; /* length to copy for repeats, bits to drop */
int ret; /* return code */
static const unsigned short order[19] = /* permutation of code lengths */
{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
/* Check that the strm exists and that the state was initialized */
if (strm == Z_NULL || strm->state == Z_NULL)
return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
/* Reset the state */
strm->msg = Z_NULL;
state->mode = TYPE;
state->last = 0;
state->whave = 0;
next = strm->next_in;
have = next != Z_NULL ? strm->avail_in : 0;
hold = 0;
bits = 0;
put = state->window;
left = state->wsize;
/* Inflate until end of block marked as last */
for (;;)
switch (state->mode) {
case TYPE:
/* determine and dispatch block type */
if (state->last) {
BYTEBITS();
state->mode = DONE;
break;
}
NEEDBITS(3);
state->last = BITS(1);
DROPBITS(1);
switch (BITS(2)) {
case 0: /* stored block */
Tracev((stderr, "inflate: stored block%s\n",
state->last ? " (last)" : ""));
state->mode = STORED;
break;
case 1: /* fixed block */
fixedtables1(state);
Tracev((stderr, "inflate: fixed codes block%s\n",
state->last ? " (last)" : ""));
state->mode = LEN; /* decode codes */
break;
case 2: /* dynamic block */
Tracev((stderr, "inflate: dynamic codes block%s\n",
state->last ? " (last)" : ""));
state->mode = TABLE;
break;
case 3:
strm->msg = (char *)"invalid block type";
state->mode = BAD;
}
DROPBITS(2);
break;
case STORED:
/* get and verify stored block length */
BYTEBITS(); /* go to byte boundary */
NEEDBITS(32);
if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
strm->msg = (char *)"invalid stored block lengths";
state->mode = BAD;
break;
}
state->length = (unsigned)hold & 0xffff;
Tracev((stderr, "inflate: stored length %u\n",
state->length));
INITBITS();
/* copy stored block from input to output */
while (state->length != 0) {
copy = state->length;
PULL();
ROOM();
if (copy > have) copy = have;
if (copy > left) copy = left;
zmemcpy(put, next, copy);
have -= copy;
next += copy;
left -= copy;
put += copy;
state->length -= copy;
}
Tracev((stderr, "inflate: stored end\n"));
state->mode = TYPE;
break;
case TABLE:
/* get dynamic table entries descriptor */
NEEDBITS(14);
state->nlen = BITS(5) + 257;
DROPBITS(5);
state->ndist = BITS(5) + 1;
DROPBITS(5);
state->ncode = BITS(4) + 4;
DROPBITS(4);
#ifndef PKZIP_BUG_WORKAROUND
if (state->nlen > 286 || state->ndist > 30) {
strm->msg = (char *)"too many length or distance symbols";
state->mode = BAD;
break;
}
#endif
Tracev((stderr, "inflate: table sizes ok\n"));
/* get code length code lengths (not a typo) */
state->have = 0;
while (state->have < state->ncode) {
NEEDBITS(3);
state->lens[order[state->have++]] = (unsigned short)BITS(3);
DROPBITS(3);
}
while (state->have < 19)
state->lens[order[state->have++]] = 0;
state->next = state->codes;
state->lencode = (code const FAR *)(state->next);
state->lenbits = 7;
ret = inflate_table(CODES, state->lens, 19, &(state->next),
&(state->lenbits), state->work);
if (ret) {
strm->msg = (char *)"invalid code lengths set";
state->mode = BAD;
break;
}
Tracev((stderr, "inflate: code lengths ok\n"));
/* get length and distance code code lengths */
state->have = 0;
while (state->have < state->nlen + state->ndist) {
for (;;) {
thisx = state->lencode[BITS(state->lenbits)];
if ((unsigned)(thisx.bits) <= bits) break;
PULLBYTE();
}
if (thisx.val < 16) {
NEEDBITS(thisx.bits);
DROPBITS(thisx.bits);
state->lens[state->have++] = thisx.val;
}
else {
if (thisx.val == 16) {
NEEDBITS(thisx.bits + 2);
DROPBITS(thisx.bits);
if (state->have == 0) {
strm->msg = (char *)"invalid bit length repeat";
state->mode = BAD;
break;
}
len = (unsigned)(state->lens[state->have - 1]);
copy = 3 + BITS(2);
DROPBITS(2);
}
else if (thisx.val == 17) {
NEEDBITS(thisx.bits + 3);
DROPBITS(thisx.bits);
len = 0;
copy = 3 + BITS(3);
DROPBITS(3);
}
else {
NEEDBITS(thisx.bits + 7);
DROPBITS(thisx.bits);
len = 0;
copy = 11 + BITS(7);
DROPBITS(7);
}
if (state->have + copy > state->nlen + state->ndist) {
strm->msg = (char *)"invalid bit length repeat";
state->mode = BAD;
break;
}
while (copy--)
state->lens[state->have++] = (unsigned short)len;
}
}
/* handle error breaks in while */
if (state->mode == BAD) break;
/* build code tables */
state->next = state->codes;
state->lencode = (code const FAR *)(state->next);
state->lenbits = 9;
ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
&(state->lenbits), state->work);
if (ret) {
strm->msg = (char *)"invalid literal/lengths set";
state->mode = BAD;
break;
}
state->distcode = (code const FAR *)(state->next);
state->distbits = 6;
ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
&(state->next), &(state->distbits), state->work);
if (ret) {
strm->msg = (char *)"invalid distances set";
state->mode = BAD;
break;
}
Tracev((stderr, "inflate: codes ok\n"));
state->mode = LEN;
case LEN:
/* use inflate_fast() if we have enough input and output */
if (have >= 6 && left >= 258) {
RESTORE();
if (state->whave < state->wsize)
state->whave = state->wsize - left;
inflate_fast(strm, state->wsize);
LOAD();
break;
}
/* get a literal, length, or end-of-block code */
for (;;) {
thisx = state->lencode[BITS(state->lenbits)];
if ((unsigned)(thisx.bits) <= bits) break;
PULLBYTE();
}
if (thisx.op && (thisx.op & 0xf0) == 0) {
last = thisx;
for (;;) {
thisx = state->lencode[last.val +
(BITS(last.bits + last.op) >> last.bits)];
if ((unsigned)(last.bits + thisx.bits) <= bits) break;
PULLBYTE();
}
DROPBITS(last.bits);
}
DROPBITS(thisx.bits);
state->length = (unsigned)thisx.val;
/* process literal */
if (thisx.op == 0) {
Tracevv((stderr, thisx.val >= 0x20 && thisx.val < 0x7f ?
"inflate: literal '%c'\n" :
"inflate: literal 0x%02x\n", thisx.val));
ROOM();
*put++ = (unsigned char)(state->length);
left--;
state->mode = LEN;
break;
}
/* process end of block */
if (thisx.op & 32) {
Tracevv((stderr, "inflate: end of block\n"));
state->mode = TYPE;
break;
}
/* invalid code */
if (thisx.op & 64) {
strm->msg = (char *)"invalid literal/length code";
state->mode = BAD;
break;
}
/* length code -- get extra bits, if any */
state->extra = (unsigned)(thisx.op) & 15;
if (state->extra != 0) {
NEEDBITS(state->extra);
state->length += BITS(state->extra);
DROPBITS(state->extra);
}
Tracevv((stderr, "inflate: length %u\n", state->length));
/* get distance code */
for (;;) {
thisx = state->distcode[BITS(state->distbits)];
if ((unsigned)(thisx.bits) <= bits) break;
PULLBYTE();
}
if ((thisx.op & 0xf0) == 0) {
last = thisx;
for (;;) {
thisx = state->distcode[last.val +
(BITS(last.bits + last.op) >> last.bits)];
if ((unsigned)(last.bits + thisx.bits) <= bits) break;
PULLBYTE();
}
DROPBITS(last.bits);
}
DROPBITS(thisx.bits);
if (thisx.op & 64) {
strm->msg = (char *)"invalid distance code";
state->mode = BAD;
break;
}
state->offset = (unsigned)thisx.val;
/* get distance extra bits, if any */
state->extra = (unsigned)(thisx.op) & 15;
if (state->extra != 0) {
NEEDBITS(state->extra);
state->offset += BITS(state->extra);
DROPBITS(state->extra);
}
if (state->offset > state->wsize - (state->whave < state->wsize ?
left : 0)) {
strm->msg = (char *)"invalid distance too far back";
state->mode = BAD;
break;
}
Tracevv((stderr, "inflate: distance %u\n", state->offset));
/* copy match from window to output */
do {
ROOM();
copy = state->wsize - state->offset;
if (copy < left) {
from = put + copy;
copy = left - copy;
}
else {
from = put - state->offset;
copy = left;
}
if (copy > state->length) copy = state->length;
state->length -= copy;
left -= copy;
do {
*put++ = *from++;
} while (--copy);
} while (state->length != 0);
break;
case DONE:
/* inflate stream terminated properly -- write leftover output */
ret = Z_STREAM_END;
if (left < state->wsize) {
if (out(out_desc, state->window, state->wsize - left))
ret = Z_BUF_ERROR;
}
goto inf_leave;
case BAD:
ret = Z_DATA_ERROR;
goto inf_leave;
default: /* can't happen, but makes compilers happy */
ret = Z_STREAM_ERROR;
goto inf_leave;
}
/* Return unused input */
inf_leave:
strm->next_in = next;
strm->avail_in = have;
return ret;
}
int ZEXPORT inflateBackEnd (z_streamp strm)
{
if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
return Z_STREAM_ERROR;
ZFREE(strm, strm->state);
strm->state = Z_NULL;
Tracev((stderr, "inflate: end\n"));
return Z_OK;
}

View File

@@ -1,316 +0,0 @@
/* inffast.c -- fast decoding
* Copyright (C) 1995-2004 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "zutil.h"
#include "inftrees.h"
#include "inflate.h"
#include "inffast.h"
#ifndef ASMINF
/* Allow machine dependent optimization for post-increment or pre-increment.
Based on testing to date,
Pre-increment preferred for:
- PowerPC G3 (Adler)
- MIPS R5000 (Randers-Pehrson)
Post-increment preferred for:
- none
No measurable difference:
- Pentium III (Anderson)
- M68060 (Nikl)
*/
#ifdef POSTINC
# define OFF 0
# define PUP(a) *(a)++
#else
# define OFF 1
# define PUP(a) *++(a)
#endif
/*
Decode literal, length, and distance codes and write out the resulting
literal and match bytes until either not enough input or output is
available, an end-of-block is encountered, or a data error is encountered.
When large enough input and output buffers are supplied to inflate(), for
example, a 16K input buffer and a 64K output buffer, more than 95% of the
inflate execution time is spent in this routine.
Entry assumptions:
state->mode == LEN
strm->avail_in >= 6
strm->avail_out >= 258
start >= strm->avail_out
state->bits < 8
On return, state->mode is one of:
LEN -- ran out of enough output space or enough available input
TYPE -- reached end of block code, inflate() to interpret next block
BAD -- error in block data
Notes:
- The maximum input bits used by a length/distance pair is 15 bits for the
length code, 5 bits for the length extra, 15 bits for the distance code,
and 13 bits for the distance extra. This totals 48 bits, or six bytes.
Therefore if strm->avail_in >= 6, then there is enough input to avoid
checking for available input while decoding.
- The maximum bytes that a single length/distance pair can output is 258
bytes, which is the maximum length that can be coded. inflate_fast()
requires strm->avail_out >= 258 for each loop to avoid checking for
output space.
*/
void inflate_fast (z_streamp strm, unsigned start)
{
struct inflate_state FAR *state;
unsigned char FAR *in; /* local strm->next_in */
unsigned char FAR *last; /* while in < last, enough input available */
unsigned char FAR *out; /* local strm->next_out */
unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
unsigned char FAR *end; /* while out < end, enough space available */
#ifdef INFLATE_STRICT
unsigned dmax; /* maximum distance from zlib header */
#endif
unsigned wsize; /* window size or zero if not using window */
unsigned whave; /* valid bytes in the window */
unsigned write; /* window write index */
unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
unsigned long hold; /* local strm->hold */
unsigned bits; /* local strm->bits */
code const FAR *lcode; /* local strm->lencode */
code const FAR *dcode; /* local strm->distcode */
unsigned lmask; /* mask for first level of length codes */
unsigned dmask; /* mask for first level of distance codes */
code thisx; /* retrieved table entry */
unsigned op; /* code bits, operation, extra bits, or */
/* window position, window bytes to copy */
unsigned len; /* match length, unused bytes */
unsigned dist; /* match distance */
unsigned char FAR *from; /* where to copy match from */
/* copy state to local variables */
state = (struct inflate_state FAR *)strm->state;
in = strm->next_in - OFF;
last = in + (strm->avail_in - 5);
out = strm->next_out - OFF;
beg = out - (start - strm->avail_out);
end = out + (strm->avail_out - 257);
#ifdef INFLATE_STRICT
dmax = state->dmax;
#endif
wsize = state->wsize;
whave = state->whave;
write = state->write;
window = state->window;
hold = state->hold;
bits = state->bits;
lcode = state->lencode;
dcode = state->distcode;
lmask = (1U << state->lenbits) - 1;
dmask = (1U << state->distbits) - 1;
/* decode literals and length/distances until end-of-block or not enough
input data or output space */
do {
if (bits < 15) {
hold += (unsigned long)(PUP(in)) << bits;
bits += 8;
hold += (unsigned long)(PUP(in)) << bits;
bits += 8;
}
thisx = lcode[hold & lmask];
dolen:
op = (unsigned)(thisx.bits);
hold >>= op;
bits -= op;
op = (unsigned)(thisx.op);
if (op == 0) { /* literal */
Tracevv((stderr, thisx.val >= 0x20 && thisx.val < 0x7f ?
"inflate: literal '%c'\n" :
"inflate: literal 0x%02x\n", thisx.val));
PUP(out) = (unsigned char)(thisx.val);
}
else if (op & 16) { /* length base */
len = (unsigned)(thisx.val);
op &= 15; /* number of extra bits */
if (op) {
if (bits < op) {
hold += (unsigned long)(PUP(in)) << bits;
bits += 8;
}
len += (unsigned)hold & ((1U << op) - 1);
hold >>= op;
bits -= op;
}
Tracevv((stderr, "inflate: length %u\n", len));
if (bits < 15) {
hold += (unsigned long)(PUP(in)) << bits;
bits += 8;
hold += (unsigned long)(PUP(in)) << bits;
bits += 8;
}
thisx = dcode[hold & dmask];
dodist:
op = (unsigned)(thisx.bits);
hold >>= op;
bits -= op;
op = (unsigned)(thisx.op);
if (op & 16) { /* distance base */
dist = (unsigned)(thisx.val);
op &= 15; /* number of extra bits */
if (bits < op) {
hold += (unsigned long)(PUP(in)) << bits;
bits += 8;
if (bits < op) {
hold += (unsigned long)(PUP(in)) << bits;
bits += 8;
}
}
dist += (unsigned)hold & ((1U << op) - 1);
#ifdef INFLATE_STRICT
if (dist > dmax) {
strm->msg = (char *)"invalid distance too far back";
state->mode = BAD;
break;
}
#endif
hold >>= op;
bits -= op;
Tracevv((stderr, "inflate: distance %u\n", dist));
op = (unsigned)(out - beg); /* max distance in output */
if (dist > op) { /* see if copy from window */
op = dist - op; /* distance back in window */
if (op > whave) {
strm->msg = (char *)"invalid distance too far back";
state->mode = BAD;
break;
}
from = window - OFF;
if (write == 0) { /* very common case */
from += wsize - op;
if (op < len) { /* some from window */
len -= op;
do {
PUP(out) = PUP(from);
} while (--op);
from = out - dist; /* rest from output */
}
}
else if (write < op) { /* wrap around window */
from += wsize + write - op;
op -= write;
if (op < len) { /* some from end of window */
len -= op;
do {
PUP(out) = PUP(from);
} while (--op);
from = window - OFF;
if (write < len) { /* some from start of window */
op = write;
len -= op;
do {
PUP(out) = PUP(from);
} while (--op);
from = out - dist; /* rest from output */
}
}
}
else { /* contiguous in window */
from += write - op;
if (op < len) { /* some from window */
len -= op;
do {
PUP(out) = PUP(from);
} while (--op);
from = out - dist; /* rest from output */
}
}
while (len > 2) {
PUP(out) = PUP(from);
PUP(out) = PUP(from);
PUP(out) = PUP(from);
len -= 3;
}
if (len) {
PUP(out) = PUP(from);
if (len > 1)
PUP(out) = PUP(from);
}
}
else {
from = out - dist; /* copy direct from output */
do { /* minimum length is three */
PUP(out) = PUP(from);
PUP(out) = PUP(from);
PUP(out) = PUP(from);
len -= 3;
} while (len > 2);
if (len) {
PUP(out) = PUP(from);
if (len > 1)
PUP(out) = PUP(from);
}
}
}
else if ((op & 64) == 0) { /* 2nd level distance code */
thisx = dcode[thisx.val + (hold & ((1U << op) - 1))];
goto dodist;
}
else {
strm->msg = (char *)"invalid distance code";
state->mode = BAD;
break;
}
}
else if ((op & 64) == 0) { /* 2nd level length code */
thisx = lcode[thisx.val + (hold & ((1U << op) - 1))];
goto dolen;
}
else if (op & 32) { /* end-of-block */
Tracevv((stderr, "inflate: end of block\n"));
state->mode = TYPE;
break;
}
else {
strm->msg = (char *)"invalid literal/length code";
state->mode = BAD;
break;
}
} while (in < last && out < end);
/* return unused bytes (on entry, bits < 8, so in won't go too far back) */
len = bits >> 3;
in -= len;
bits -= len << 3;
hold &= (1U << bits) - 1;
/* update state and return */
strm->next_in = in + OFF;
strm->next_out = out + OFF;
strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
strm->avail_out = (unsigned)(out < end ?
257 + (end - out) : 257 - (out - end));
state->hold = hold;
state->bits = bits;
return;
}
/*
inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
- Using bit fields for code structure
- Different op definition to avoid & for extra bits (do & for table bits)
- Three separate decoding do-loops for direct, window, and write == 0
- Special case for distance > 1 copies to do overlapped load and store copy
- Explicit branch predictions (based on measured branch probabilities)
- Deferring match copy and interspersed it with decoding subsequent codes
- Swapping literal/length else
- Swapping window/direct else
- Larger unrolled copy loops (three is about right)
- Moving len -= 3 statement into middle of loop
*/
#endif /* !ASMINF */

View File

@@ -1,11 +0,0 @@
/* inffast.h -- header to use inffast.c
* Copyright (C) 1995-2003 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
void inflate_fast OF((z_streamp strm, unsigned start));

View File

@@ -1,94 +0,0 @@
/* inffixed.h -- table for decoding fixed codes
* Generated automatically by makefixed().
*/
/* WARNING: this file should *not* be used by applications. It
is part of the implementation of the compression library and
is subject to change. Applications should only use zlib.h.
*/
static const code lenfix[512] = {
{96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
{0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
{0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
{0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
{0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
{21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
{0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
{0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
{18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
{0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
{0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
{0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
{20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
{0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
{0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
{0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
{16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
{0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
{0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
{0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
{0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
{0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
{0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
{0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
{17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
{0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
{0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
{0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
{19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
{0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
{0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
{0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
{16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
{0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
{0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
{0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
{0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
{20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
{0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
{0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
{17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
{0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
{0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
{0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
{20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
{0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
{0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
{0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
{16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
{0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
{0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
{0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
{0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
{0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
{0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
{0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
{16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
{0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
{0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
{0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
{19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
{0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
{0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
{0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
{16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
{0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
{0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
{0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
{0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
{64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
{0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
{0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
{18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
{0,9,255}
};
static const code distfix[32] = {
{16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
{21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
{18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
{19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
{16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
{22,5,193},{64,5,0}
};

File diff suppressed because it is too large Load Diff

View File

@@ -1,121 +0,0 @@
/* inflate.h -- internal inflate state definition
* Copyright (C) 1995-2004 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
#ifndef _INFLATE_H_
#define _INFLATE_H_
/* define NO_GZIP when compiling if you want to disable gzip header and
trailer decoding by inflate(). NO_GZIP would be used to avoid linking in
the crc code when it is not needed. For shared libraries, gzip decoding
should be left enabled. */
#ifndef NO_GZIP
# define GUNZIP
#endif
/* Possible inflate modes between inflate() calls */
typedef enum {
HEAD, /* i: waiting for magic header */
FLAGS, /* i: waiting for method and flags (gzip) */
TIME, /* i: waiting for modification time (gzip) */
OS, /* i: waiting for extra flags and operating system (gzip) */
EXLEN, /* i: waiting for extra length (gzip) */
EXTRA, /* i: waiting for extra bytes (gzip) */
NAME, /* i: waiting for end of file name (gzip) */
COMMENT, /* i: waiting for end of comment (gzip) */
HCRC, /* i: waiting for header crc (gzip) */
DICTID, /* i: waiting for dictionary check value */
DICT, /* waiting for inflateSetDictionary() call */
TYPE, /* i: waiting for type bits, including last-flag bit */
TYPEDO, /* i: same, but skip check to exit inflate on new block */
STORED, /* i: waiting for stored size (length and complement) */
COPY, /* i/o: waiting for input or output to copy stored block */
TABLE, /* i: waiting for dynamic block table lengths */
LENLENS, /* i: waiting for code length code lengths */
CODELENS, /* i: waiting for length/lit and distance code lengths */
LEN, /* i: waiting for length/lit code */
LENEXT, /* i: waiting for length extra bits */
DIST, /* i: waiting for distance code */
DISTEXT, /* i: waiting for distance extra bits */
MATCH, /* o: waiting for output space to copy string */
LIT, /* o: waiting for output space to write literal */
CHECK, /* i: waiting for 32-bit check value */
LENGTH, /* i: waiting for 32-bit length (gzip) */
DONE, /* finished check, done -- remain here until reset */
BAD, /* got a data error -- remain here until reset */
MEM, /* got an inflate() memory error -- remain here until reset */
SYNC /* looking for synchronization bytes to restart inflate() */
} inflate_mode;
/*
State transitions between above modes -
(most modes can go to the BAD or MEM mode -- not shown for clarity)
Process header:
HEAD -> (gzip) or (zlib)
(gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
NAME -> COMMENT -> HCRC -> TYPE
(zlib) -> DICTID or TYPE
DICTID -> DICT -> TYPE
Read deflate blocks:
TYPE -> STORED or TABLE or LEN or CHECK
STORED -> COPY -> TYPE
TABLE -> LENLENS -> CODELENS -> LEN
Read deflate codes:
LEN -> LENEXT or LIT or TYPE
LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
LIT -> LEN
Process trailer:
CHECK -> LENGTH -> DONE
*/
/* state maintained between inflate() calls. Approximately 7K bytes. */
struct inflate_state {
inflate_mode mode; /* current inflate mode */
int last; /* true if processing last block */
int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
int havedict; /* true if dictionary provided */
int flags; /* gzip header method and flags (0 if zlib) */
unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
unsigned long check; /* protected copy of check value */
unsigned long total; /* protected copy of output count */
gz_headerp head; /* where to save gzip header information */
/* sliding window */
unsigned wbits; /* log base 2 of requested window size */
unsigned wsize; /* window size or zero if not using window */
unsigned whave; /* valid bytes in the window */
unsigned write; /* window write index */
unsigned char FAR *window; /* allocated sliding window, if needed */
/* bit accumulator */
unsigned long hold; /* input bit accumulator */
unsigned bits; /* number of bits in "in" */
/* for string and stored block copying */
unsigned length; /* literal or length of data to copy */
unsigned offset; /* distance back to copy string from */
/* for table and code decoding */
unsigned extra; /* extra bits needed */
/* fixed and dynamic code tables */
code const FAR *lencode; /* starting table for length/literal codes */
code const FAR *distcode; /* starting table for distance codes */
unsigned lenbits; /* index bits for lencode */
unsigned distbits; /* index bits for distcode */
/* dynamic table building */
unsigned ncode; /* number of code length code lengths */
unsigned nlen; /* number of length code lengths */
unsigned ndist; /* number of distance code lengths */
unsigned have; /* number of code lengths in lens[] */
code FAR *next; /* next available space in codes[] */
unsigned short lens[320]; /* temporary storage for code lengths */
unsigned short work[288]; /* work area for code table building */
code codes[ENOUGH]; /* space for code tables */
};
#endif

View File

@@ -1,328 +0,0 @@
/* inftrees.c -- generate Huffman trees for efficient decoding
* Copyright (C) 1995-2005 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "zutil.h"
#include "inftrees.h"
#define MAXBITS 15
const char inflate_copyright[] =
" inflate 1.2.3 Copyright 1995-2005 Mark Adler ";
/*
If you use the zlib library in a product, an acknowledgment is welcome
in the documentation of your product. If for some reason you cannot
include such an acknowledgment, I would appreciate that you keep this
copyright string in the executable of your product.
*/
/*
Build a set of tables to decode the provided canonical Huffman code.
The code lengths are lens[0..codes-1]. The result starts at *table,
whose indices are 0..2^bits-1. work is a writable array of at least
lens shorts, which is used as a work area. type is the type of code
to be generated, CODES, LENS, or DISTS. On return, zero is success,
-1 is an invalid code, and +1 means that ENOUGH isn't enough. table
on return points to the next available entry's address. bits is the
requested root table index bits, and on return it is the actual root
table index bits. It will differ if the request is greater than the
longest code or if it is less than the shortest code.
*/
int inflate_table (codetype type,
unsigned short FAR *lens,
unsigned codes,
code FAR * FAR *table,
unsigned FAR *bits,
unsigned short FAR *work)
{
unsigned len; /* a code's length in bits */
unsigned sym; /* index of code symbols */
unsigned min, max; /* minimum and maximum code lengths */
unsigned root; /* number of index bits for root table */
unsigned curr; /* number of index bits for current table */
unsigned drop; /* code bits to drop for sub-table */
int left; /* number of prefix codes available */
unsigned used; /* code entries in table used */
unsigned huff; /* Huffman code */
unsigned incr; /* for incrementing code, index */
unsigned fill; /* index for replicating entries */
unsigned low; /* low bits for current root entry */
unsigned mask; /* mask for low root bits */
code thisx; /* table entry for duplication */
code FAR *next; /* next available space in table */
const unsigned short FAR *base; /* base value table to use */
const unsigned short FAR *extra; /* extra bits table to use */
int end; /* use base and extra for symbol > end */
unsigned short count[MAXBITS+1]; /* number of codes of each length */
unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
static const unsigned short lbase[31] = { /* Length codes 257..285 base */
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
static const unsigned short lext[31] = { /* Length codes 257..285 extra */
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196};
static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
8193, 12289, 16385, 24577, 0, 0};
static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
28, 28, 29, 29, 64, 64};
/*
Process a set of code lengths to create a canonical Huffman code. The
code lengths are lens[0..codes-1]. Each length corresponds to the
symbols 0..codes-1. The Huffman code is generated by first sorting the
symbols by length from short to long, and retaining the symbol order
for codes with equal lengths. Then the code starts with all zero bits
for the first code of the shortest length, and the codes are integer
increments for the same length, and zeros are appended as the length
increases. For the deflate format, these bits are stored backwards
from their more natural integer increment ordering, and so when the
decoding tables are built in the large loop below, the integer codes
are incremented backwards.
This routine assumes, but does not check, that all of the entries in
lens[] are in the range 0..MAXBITS. The caller must assure this.
1..MAXBITS is interpreted as that code length. zero means that that
symbol does not occur in this code.
The codes are sorted by computing a count of codes for each length,
creating from that a table of starting indices for each length in the
sorted table, and then entering the symbols in order in the sorted
table. The sorted table is work[], with that space being provided by
the caller.
The length counts are used for other purposes as well, i.e. finding
the minimum and maximum length codes, determining if there are any
codes at all, checking for a valid set of lengths, and looking ahead
at length counts to determine sub-table sizes when building the
decoding tables.
*/
/* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
for (len = 0; len <= MAXBITS; len++)
count[len] = 0;
for (sym = 0; sym < codes; sym++)
count[lens[sym]]++;
/* bound code lengths, force root to be within code lengths */
root = *bits;
for (max = MAXBITS; max >= 1; max--)
if (count[max] != 0) break;
if (root > max) root = max;
if (max == 0) { /* no symbols to code at all */
thisx.op = (unsigned char)64; /* invalid code marker */
thisx.bits = (unsigned char)1;
thisx.val = (unsigned short)0;
*(*table)++ = thisx; /* make a table to force an error */
*(*table)++ = thisx;
*bits = 1;
return 0; /* no symbols, but wait for decoding to report error */
}
for (min = 1; min <= MAXBITS; min++)
if (count[min] != 0) break;
if (root < min) root = min;
/* check for an over-subscribed or incomplete set of lengths */
left = 1;
for (len = 1; len <= MAXBITS; len++) {
left <<= 1;
left -= count[len];
if (left < 0) return -1; /* over-subscribed */
}
if (left > 0 && (type == CODES || max != 1))
return -1; /* incomplete set */
/* generate offsets into symbol table for each length for sorting */
offs[1] = 0;
for (len = 1; len < MAXBITS; len++)
offs[len + 1] = offs[len] + count[len];
/* sort symbols by length, by symbol order within each length */
for (sym = 0; sym < codes; sym++)
if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
/*
Create and fill in decoding tables. In this loop, the table being
filled is at next and has curr index bits. The code being used is huff
with length len. That code is converted to an index by dropping drop
bits off of the bottom. For codes where len is less than drop + curr,
those top drop + curr - len bits are incremented through all values to
fill the table with replicated entries.
root is the number of index bits for the root table. When len exceeds
root, sub-tables are created pointed to by the root entry with an index
of the low root bits of huff. This is saved in low to check for when a
new sub-table should be started. drop is zero when the root table is
being filled, and drop is root when sub-tables are being filled.
When a new sub-table is needed, it is necessary to look ahead in the
code lengths to determine what size sub-table is needed. The length
counts are used for this, and so count[] is decremented as codes are
entered in the tables.
used keeps track of how many table entries have been allocated from the
provided *table space. It is checked when a LENS table is being made
against the space in *table, ENOUGH, minus the maximum space needed by
the worst case distance code, MAXD. This should never happen, but the
sufficiency of ENOUGH has not been proven exhaustively, hence the check.
This assumes that when type == LENS, bits == 9.
sym increments through all symbols, and the loop terminates when
all codes of length max, i.e. all codes, have been processed. This
routine permits incomplete codes, so another loop after this one fills
in the rest of the decoding tables with invalid code markers.
*/
/* set up for code type */
switch (type) {
case CODES:
base = extra = work; /* dummy value--not used */
end = 19;
break;
case LENS:
base = lbase;
base -= 257;
extra = lext;
extra -= 257;
end = 256;
break;
default: /* DISTS */
base = dbase;
extra = dext;
end = -1;
}
/* initialize state for loop */
huff = 0; /* starting code */
sym = 0; /* starting code symbol */
len = min; /* starting code length */
next = *table; /* current table to fill in */
curr = root; /* current table index bits */
drop = 0; /* current bits to drop from code for index */
low = (unsigned)(-1); /* trigger new sub-table when len > root */
used = 1U << root; /* use root table entries */
mask = used - 1; /* mask for comparing low */
/* check available table space */
if (type == LENS && used >= ENOUGH - MAXD)
return 1;
/* process all codes and make table entries */
for (;;) {
/* create table entry */
thisx.bits = (unsigned char)(len - drop);
if ((int)(work[sym]) < end) {
thisx.op = (unsigned char)0;
thisx.val = work[sym];
}
else if ((int)(work[sym]) > end) {
thisx.op = (unsigned char)(extra[work[sym]]);
thisx.val = base[work[sym]];
}
else {
thisx.op = (unsigned char)(32 + 64); /* end of block */
thisx.val = 0;
}
/* replicate for those indices with low len bits equal to huff */
incr = 1U << (len - drop);
fill = 1U << curr;
min = fill; /* save offset to next table */
do {
fill -= incr;
next[(huff >> drop) + fill] = thisx;
} while (fill != 0);
/* backwards increment the len-bit code huff */
incr = 1U << (len - 1);
while (huff & incr)
incr >>= 1;
if (incr != 0) {
huff &= incr - 1;
huff += incr;
}
else
huff = 0;
/* go to next symbol, update count, len */
sym++;
if (--(count[len]) == 0) {
if (len == max) break;
len = lens[work[sym]];
}
/* create new sub-table if needed */
if (len > root && (huff & mask) != low) {
/* if first time, transition to sub-tables */
if (drop == 0)
drop = root;
/* increment past last table */
next += min; /* here min is 1 << curr */
/* determine length of next table */
curr = len - drop;
left = (int)(1 << curr);
while (curr + drop < max) {
left -= count[curr + drop];
if (left <= 0) break;
curr++;
left <<= 1;
}
/* check for enough space */
used += 1U << curr;
if (type == LENS && used >= ENOUGH - MAXD)
return 1;
/* point entry in root table to sub-table */
low = huff & mask;
(*table)[low].op = (unsigned char)curr;
(*table)[low].bits = (unsigned char)root;
(*table)[low].val = (unsigned short)(next - *table);
}
}
/*
Fill in rest of table for incomplete codes. This loop is similar to the
loop above in incrementing huff for table indices. It is assumed that
len is equal to curr + drop, so there is no loop needed to increment
through high index bits. When the current sub-table is filled, the loop
drops back to the root table to fill in any remaining entries there.
*/
thisx.op = (unsigned char)64; /* invalid code marker */
thisx.bits = (unsigned char)(len - drop);
thisx.val = (unsigned short)0;
while (huff != 0) {
/* when done with sub-table, drop back to root table */
if (drop != 0 && (huff & mask) != low) {
drop = 0;
len = root;
next = *table;
thisx.bits = (unsigned char)len;
}
/* put invalid code marker in table */
next[huff >> drop] = thisx;
/* backwards increment the len-bit code huff */
incr = 1U << (len - 1);
while (huff & incr)
incr >>= 1;
if (incr != 0) {
huff &= incr - 1;
huff += incr;
}
else
huff = 0;
}
/* set return parameters */
*table += used;
*bits = root;
return 0;
}

View File

@@ -1,61 +0,0 @@
/* inftrees.h -- header to use inftrees.c
* Copyright (C) 1995-2005 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
#ifndef _INFTREES_H_
#define _INFTREES_H_
/* Structure for decoding tables. Each entry provides either the
information needed to do the operation requested by the code that
indexed that table entry, or it provides a pointer to another
table that indexes more bits of the code. op indicates whether
the entry is a pointer to another table, a literal, a length or
distance, an end-of-block, or an invalid code. For a table
pointer, the low four bits of op is the number of index bits of
that table. For a length or distance, the low four bits of op
is the number of extra bits to get after the code. bits is
the number of bits in this code or part of the code to drop off
of the bit buffer. val is the actual byte to output in the case
of a literal, the base length or distance, or the offset from
the current table to the next table. Each entry is four bytes. */
typedef struct {
unsigned char op; /* operation, extra bits, table bits */
unsigned char bits; /* bits in this part of the code */
unsigned short val; /* offset in table or code value */
} code;
/* op values as set by inflate_table():
00000000 - literal
0000tttt - table link, tttt != 0 is the number of table index bits
0001eeee - length or distance, eeee is the number of extra bits
01100000 - end of block
01000000 - invalid code
*/
/* Maximum size of dynamic tree. The maximum found in a long but non-
exhaustive search was 1444 code structures (852 for length/literals
and 592 for distances, the latter actually the result of an
exhaustive search). The true maximum is not known, but the value
below is more than safe. */
#define ENOUGH 2048
#define MAXD 592
/* Type of code to build for inftable() */
typedef enum {
CODES,
LENS,
DISTS
} codetype;
extern int inflate_table OF((codetype type, unsigned short FAR *lens,
unsigned codes, code FAR * FAR *table,
unsigned FAR *bits, unsigned short FAR *work));
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,127 +0,0 @@
/* header created automatically with -DGEN_TREES_H */
local const ct_data static_ltree[L_CODES+2] = {
{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
};
local const ct_data static_dtree[D_CODES] = {
{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
};
const uch _dist_code[DIST_CODE_LEN] = {
0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
};
const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
};
local const int base_length[LENGTH_CODES] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
64, 80, 96, 112, 128, 160, 192, 224, 0
};
local const int base_dist[D_CODES] = {
0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
};

View File

@@ -1,60 +0,0 @@
/* uncompr.c -- decompress a memory buffer
* Copyright (C) 1995-2003 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id: uncompr.c,v 1.1 2007/06/07 17:54:37 jules_rms Exp $ */
#define ZLIB_INTERNAL
#include "zlib.h"
/* ===========================================================================
Decompresses the source buffer into the destination buffer. sourceLen is
the byte length of the source buffer. Upon entry, destLen is the total
size of the destination buffer, which must be large enough to hold the
entire uncompressed data. (The size of the uncompressed data must have
been saved previously by the compressor and transmitted to the decompressor
by some mechanism outside the scope of this compression library.)
Upon exit, destLen is the actual size of the compressed buffer.
This function can be used to decompress a whole file at once if the
input file is mmap'ed.
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_BUF_ERROR if there was not enough room in the output
buffer, or Z_DATA_ERROR if the input data was corrupted.
*/
int ZEXPORT uncompress (Bytef *dest,
uLongf *destLen,
const Bytef *source,
uLong sourceLen)
{
z_stream stream;
int err;
stream.next_in = (Bytef*)source;
stream.avail_in = (uInt)sourceLen;
/* Check for source > 64K on 16-bit machine: */
if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
stream.next_out = dest;
stream.avail_out = (uInt)*destLen;
if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
stream.zalloc = (alloc_func)0;
stream.zfree = (free_func)0;
err = inflateInit(&stream);
if (err != Z_OK) return err;
err = inflate(&stream, Z_FINISH);
if (err != Z_STREAM_END) {
inflateEnd(&stream);
if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
return Z_DATA_ERROR;
return err;
}
*destLen = stream.total_out;
err = inflateEnd(&stream);
return err;
}

View File

@@ -1,345 +0,0 @@
/* zconf.h -- configuration of the zlib compression library
* Copyright (C) 1995-2005 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id: zconf.h,v 1.1 2007/06/07 17:54:37 jules_rms Exp $ */
#ifndef ZCONF_H
#define ZCONF_H
// *** Just a few hacks here to make it compile nicely with Beast..
#define Z_PREFIX 1
#undef __MACTYPES__
#ifdef _MSC_VER
#pragma warning (disable : 4131 4127 4244 4267)
#endif
/*
* If you *really* need a unique prefix for all types and library functions,
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
*/
#ifdef Z_PREFIX
# define deflateInit_ z_deflateInit_
# define deflate z_deflate
# define deflateEnd z_deflateEnd
# define inflateInit_ z_inflateInit_
# define inflate z_inflate
# define inflateEnd z_inflateEnd
# define inflatePrime z_inflatePrime
# define inflateGetHeader z_inflateGetHeader
# define adler32_combine z_adler32_combine
# define crc32_combine z_crc32_combine
# define deflateInit2_ z_deflateInit2_
# define deflateSetDictionary z_deflateSetDictionary
# define deflateCopy z_deflateCopy
# define deflateReset z_deflateReset
# define deflateParams z_deflateParams
# define deflateBound z_deflateBound
# define deflatePrime z_deflatePrime
# define inflateInit2_ z_inflateInit2_
# define inflateSetDictionary z_inflateSetDictionary
# define inflateSync z_inflateSync
# define inflateSyncPoint z_inflateSyncPoint
# define inflateCopy z_inflateCopy
# define inflateReset z_inflateReset
# define inflateBack z_inflateBack
# define inflateBackEnd z_inflateBackEnd
# define compress z_compress
# define compress2 z_compress2
# define compressBound z_compressBound
# define uncompress z_uncompress
# define adler32 z_adler32
# define crc32 z_crc32
# define get_crc_table z_get_crc_table
# define zError z_zError
# define alloc_func z_alloc_func
# define free_func z_free_func
# define in_func z_in_func
# define out_func z_out_func
# define Byte z_Byte
# define uInt z_uInt
# define uLong z_uLong
# define Bytef z_Bytef
# define charf z_charf
# define intf z_intf
# define uIntf z_uIntf
# define uLongf z_uLongf
# define voidpf z_voidpf
# define voidp z_voidp
#endif
#if defined(__MSDOS__) && !defined(MSDOS)
# define MSDOS
#endif
#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
# define OS2
#endif
#if defined(_WINDOWS) && !defined(WINDOWS)
# define WINDOWS
#endif
#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
# ifndef WIN32
# define WIN32
# endif
#endif
#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
# ifndef SYS16BIT
# define SYS16BIT
# endif
# endif
#endif
/*
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more
* than 64k bytes at a time (needed on systems with 16-bit int).
*/
#ifdef SYS16BIT
# define MAXSEG_64K
#endif
#ifdef MSDOS
# define UNALIGNED_OK
#endif
#ifdef __STDC_VERSION__
# ifndef STDC
# define STDC
# endif
# if __STDC_VERSION__ >= 199901L
# ifndef STDC99
# define STDC99
# endif
# endif
#endif
#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
# define STDC
#endif
#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
# define STDC
#endif
#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
# define STDC
#endif
#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
# define STDC
#endif
#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
# define STDC
#endif
#ifndef STDC
# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
# define const /* note: need a more gentle solution here */
# endif
#endif
/* Some Mac compilers merge all .h files incorrectly: */
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
# define NO_DUMMY_DECL
#endif
/* Maximum value for memLevel in deflateInit2 */
#ifndef MAX_MEM_LEVEL
# ifdef MAXSEG_64K
# define MAX_MEM_LEVEL 8
# else
# define MAX_MEM_LEVEL 9
# endif
#endif
/* Maximum value for windowBits in deflateInit2 and inflateInit2.
* WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
* created by gzip. (Files created by minigzip can still be extracted by
* gzip.)
*/
#ifndef MAX_WBITS
# define MAX_WBITS 15 /* 32K LZ77 window */
#endif
/* The memory requirements for deflate are (in bytes):
(1 << (windowBits+2)) + (1 << (memLevel+9))
that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
plus a few kilobytes for small objects. For example, if you want to reduce
the default memory requirements from 256K to 128K, compile with
make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
Of course this will generally degrade compression (there's no free lunch).
The memory requirements for inflate are (in bytes) 1 << windowBits
that is, 32K for windowBits=15 (default value) plus a few kilobytes
for small objects.
*/
/* Type declarations */
#ifndef OF /* function prototypes */
# ifdef STDC
# define OF(args) args
# else
# define OF(args) ()
# endif
#endif
/* The following definitions for FAR are needed only for MSDOS mixed
* model programming (small or medium model with some far allocations).
* This was tested only with MSC; for other MSDOS compilers you may have
* to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
* just define FAR to be empty.
*/
#ifdef SYS16BIT
# if defined(M_I86SM) || defined(M_I86MM)
/* MSC small or medium model */
# define SMALL_MEDIUM
# ifdef _MSC_VER
# define FAR _far
# else
# define FAR far
# endif
# endif
# if (defined(__SMALL__) || defined(__MEDIUM__))
/* Turbo C small or medium model */
# define SMALL_MEDIUM
# ifdef __BORLANDC__
# define FAR _far
# else
# define FAR far
# endif
# endif
#endif
#if defined(WINDOWS) || defined(WIN32)
/* If building or using zlib as a DLL, define ZLIB_DLL.
* This is not mandatory, but it offers a little performance increase.
*/
# ifdef ZLIB_DLL
# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
# ifdef ZLIB_INTERNAL
# define ZEXTERN extern __declspec(dllexport)
# else
# define ZEXTERN extern __declspec(dllimport)
# endif
# endif
# endif /* ZLIB_DLL */
/* If building or using zlib with the WINAPI/WINAPIV calling convention,
* define ZLIB_WINAPI.
* Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
*/
# ifdef ZLIB_WINAPI
# ifdef FAR
# undef FAR
# endif
# include <windows.h>
/* No need for _export, use ZLIB.DEF instead. */
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
# define ZEXPORT WINAPI
# ifdef WIN32
# define ZEXPORTVA WINAPIV
# else
# define ZEXPORTVA FAR CDECL
# endif
# endif
#endif
#if defined (__BEOS__)
# ifdef ZLIB_DLL
# ifdef ZLIB_INTERNAL
# define ZEXPORT __declspec(dllexport)
# define ZEXPORTVA __declspec(dllexport)
# else
# define ZEXPORT __declspec(dllimport)
# define ZEXPORTVA __declspec(dllimport)
# endif
# endif
#endif
#ifndef ZEXTERN
# define ZEXTERN extern
#endif
#ifndef ZEXPORT
# define ZEXPORT
#endif
#ifndef ZEXPORTVA
# define ZEXPORTVA
#endif
#ifndef FAR
# define FAR
#endif
#if !defined(__MACTYPES__)
typedef unsigned char Byte; /* 8 bits */
#endif
typedef unsigned int uInt; /* 16 bits or more */
typedef unsigned long uLong; /* 32 bits or more */
#ifdef SMALL_MEDIUM
/* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
# define Bytef Byte FAR
#else
typedef Byte FAR Bytef;
#endif
typedef char FAR charf;
typedef int FAR intf;
typedef uInt FAR uIntf;
typedef uLong FAR uLongf;
#ifdef STDC
typedef void const *voidpc;
typedef void FAR *voidpf;
typedef void *voidp;
#else
typedef Byte const *voidpc;
typedef Byte FAR *voidpf;
typedef Byte *voidp;
#endif
#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
# include <sys/types.h> /* for off_t */
# include <unistd.h> /* for SEEK_* and off_t */
# ifdef VMS
# include <unixio.h> /* for off_t */
# endif
# define z_off_t off_t
#endif
#ifndef SEEK_SET
# define SEEK_SET 0 /* Seek from beginning of file. */
# define SEEK_CUR 1 /* Seek from current position. */
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
#endif
#ifndef z_off_t
# define z_off_t long
#endif
#if defined(__OS400__)
# define NO_vsnprintf
#endif
#if defined(__MVS__)
# define NO_vsnprintf
# ifdef FAR
# undef FAR
# endif
#endif
/* MVS linker does not support external names larger than 8 bytes */
#if defined(__MVS__)
# pragma map(deflateInit_,"DEIN")
# pragma map(deflateInit2_,"DEIN2")
# pragma map(deflateEnd,"DEEND")
# pragma map(deflateBound,"DEBND")
# pragma map(inflateInit_,"ININ")
# pragma map(inflateInit2_,"ININ2")
# pragma map(inflateEnd,"INEND")
# pragma map(inflateSync,"INSY")
# pragma map(inflateSetDictionary,"INSEDI")
# pragma map(compressBound,"CMBND")
# pragma map(inflate_table,"INTABL")
# pragma map(inflate_fast,"INFA")
# pragma map(inflate_copyright,"INCOPY")
#endif
#endif /* ZCONF_H */

Some files were not shown because too many files have changed in this diff Show More