Add functionality

This commit is contained in:
Mikhail Lobotskiy
2024-10-24 20:57:29 +04:00
parent 00344df9ad
commit fd90f73c19
6 changed files with 198 additions and 4 deletions

View File

@ -99,6 +99,11 @@ namespace NSJSON
return m_internal->m_type == CTypedValue::vtObject;
}
bool IValue::IsImage() const
{
return m_internal->m_type == CTypedValue::vtImage;
}
bool IValue::ToBool() const
{
if (m_internal->m_type != CTypedValue::vtPrimitive)
@ -350,6 +355,11 @@ namespace NSJSON
strRes += "}";
break;
}
case CTypedValue::vtImage:
{
// TODO: implement like typed array?
break;
}
}
return strRes;
@ -497,6 +507,58 @@ namespace NSJSON
return static_cast<CObject*>(m_internal->m_value.get())->getPropertyNames();
}
const BYTE* IValue::GetImageBits() const
{
if (m_internal->m_type != CTypedValue::vtImage)
{
#ifdef JSON_DEBUG
throw std::bad_cast();
#endif
return nullptr;
}
return static_cast<CImage*>(m_internal->m_value.get())->getBits();
}
BYTE* IValue::GetImageBits()
{
return const_cast<BYTE*>(static_cast<const CValue&>(*this).GetImageBits());
}
int IValue::GetImageWidth() const
{
if (m_internal->m_type != CTypedValue::vtImage)
{
#ifdef JSON_DEBUG
throw std::bad_cast();
#endif
return 0;
}
return static_cast<CImage*>(m_internal->m_value.get())->getWidth();
}
int IValue::GetImageHeight() const
{
if (m_internal->m_type != CTypedValue::vtImage)
{
#ifdef JSON_DEBUG
throw std::bad_cast();
#endif
return 0;
}
return static_cast<CImage*>(m_internal->m_value.get())->getHeight();
}
ImageFormat IValue::GetImageFormat() const
{
if (m_internal->m_type != CTypedValue::vtImage)
{
#ifdef JSON_DEBUG
throw std::bad_cast();
#endif
return ifInvalid;
}
return static_cast<CImage*>(m_internal->m_value.get())->getFormat();
}
CValue::CValue() : IValue()
{
@ -590,6 +652,27 @@ namespace NSJSON
NSJSBase::NSAllocator::Free(data, size);
}
CValue CValue::CreateImage(BYTE* bits, int width, int height, ImageFormat format, bool isExternalize)
{
CValue ret;
if (width <= 0 || height <= 0)
return ret;
ret.m_internal->m_value = std::make_shared<CImage>(bits, width, height, format, isExternalize);
ret.m_internal->m_type = CTypedValue::vtImage;
return ret;
}
BYTE* CValue::AllocImageBits(int width, int height)
{
return new BYTE[width * height];
}
void CValue::FreeImageBits(BYTE* bits)
{
delete[] bits;
}
CValue CValue::CreateObject()
{
CValue ret;

View File

@ -20,7 +20,7 @@
#endif
// uncomment to enable exceptions throwing
//#define JSON_DEBUG
// #define JSON_DEBUG
#ifdef JSON_DEBUG
#include <stdexcept>
@ -29,6 +29,14 @@
namespace NSJSON
{
typedef unsigned char BYTE;
enum ImageFormat
{
ifRGBA,
ifBGRA,
ifARGB,
ifInvalid
};
class CValue;
class CValueRef;
@ -88,6 +96,10 @@ namespace NSJSON
* Returns true if the value is an object.
*/
bool IsObject() const;
/**
* Returns true if the value is an image.
*/
bool IsImage() const;
// FUNCTIONS FOR WORKING WITH PRIMITIVE VALUES
/**
@ -193,6 +205,29 @@ namespace NSJSON
*/
std::vector<std::string> GetPropertyNames() const;
// FUNCTIONS FOR WORKING WITH IMAGES
/**
* Gets bits of image.
* @return the pointer to memory, allocated for the image. If current value is not an image, returns nullptr.
*/
const BYTE* GetImageBits() const;
BYTE* GetImageBits();
/**
* Gets width of the image.
* @returns Returns the width of the image. If current value is not an image, returns 0.
*/
int GetImageWidth() const;
/**
* Gets height of the image.
* @returns Returns the height of the image. If current value is not an image, returns 0.
*/
int GetImageHeight() const;
/**
* Gets format of the image.
* @returns Returns the image format. If current value is not an image, returns ImageFormat::ifInvalid.
*/
ImageFormat GetImageFormat() const;
protected:
std::shared_ptr<CTypedValue> m_internal;
};
@ -251,6 +286,29 @@ namespace NSJSON
*/
static void FreeTypedArray(BYTE* data, size_t size);
// IMAGE
/**
* Creates and returns new image object.
* @param bits The pointer to image data. The pointer should be acquired with AllocImageBits().
* @param width The width of the image.
* @param height The height of the image.
* @param format The format of the image.
* @param isExternalize If true the memory will not be reclaimed when the created image is destroyed.
* If this parameter is false then the memory will be released using FreeImageBits() during the image object destruction.
*/
static CValue CreateImage(BYTE* bits, int width, int height, ImageFormat format, bool isExternalize = true);
/**
* Allocates the memory for an image.
* @param width The width of the image.
* @param height The height of the image.
*/
static BYTE* AllocImageBits(int width, int height);
/**
* Frees the memory for a image bits.
* @param data The allocated memory to be released.
*/
static void FreeImageBits(BYTE* bits);
// OBJECT CONSTRUCTOR
/**
* Creates and returns empty object.

View File

@ -17,7 +17,8 @@ namespace NSJSON
vtPrimitive,
vtArray,
vtTypedArray,
vtObject
vtObject,
vtImage
};
public:

View File

@ -211,4 +211,36 @@ namespace NSJSON
}
return ret;
}
CImage::CImage(BYTE* bits, int width, int height, ImageFormat format, bool isExternalize) : m_bits(bits), m_width(width), m_height(height), m_format(format), m_isExternalize(isExternalize)
{
}
CImage::~CImage()
{
if (!m_isExternalize)
{
CValue::FreeImageBits(m_bits);
}
}
BYTE* CImage::getBits()
{
return m_bits;
}
int CImage::getWidth()
{
return m_width;
}
int CImage::getHeight()
{
return m_height;
}
ImageFormat CImage::getFormat()
{
return m_format;
}
}

View File

@ -113,6 +113,26 @@ namespace NSJSON
private:
storage_t m_values;
};
}
class CImage : public IBaseValue
{
public:
CImage(BYTE* bits, int width, int height, ImageFormat format, bool isExternalize = true);
~CImage();
public:
BYTE* getBits();
int getWidth();
int getHeight();
ImageFormat getFormat();
private:
BYTE* m_bits;
int m_width;
int m_height;
ImageFormat m_format;
bool m_isExternalize;
};
} // namespace
#endif // JSON_VALUES_H_

View File

@ -10,7 +10,7 @@ namespace NSJSON
{
static JSSmart<NSJSBase::CJSValue> toJS(const CValue& value)
{
if (value.IsUndefined())
if (value.IsUndefined() || value.IsImage())
return NSJSBase::CJSContext::createUndefined();
if (value.IsNull())
return NSJSBase::CJSContext::createNull();