See More

#include "core.h" #ifdef _MACOSX #include #endif //////////////////////////////////////////////////////////////////////////////// struct MCBinaryEncoder { uint32_t capacity; uint32_t frontier; void *buffer; }; bool MCBinaryEncoderCreate(MCBinaryEncoder*& r_encoder) { if (!MCMemoryNew(r_encoder)) return false; r_encoder -> capacity = 0; r_encoder -> frontier = 0; r_encoder -> buffer = nil; return true; } void MCBinaryEncoderDestroy(MCBinaryEncoder *self) { if (self == nil) return; MCMemoryDeallocate(self -> buffer); MCMemoryDelete(self); } void MCBinaryEncoderBorrow(MCBinaryEncoder *self, void*& r_buffer, uint32_t& r_buffer_length) { r_buffer = self -> buffer; r_buffer_length = self -> frontier; } bool MCBinaryEncoderWriteBytes(MCBinaryEncoder *self, const void *p_data, uint32_t p_length) { if (self -> frontier + p_length > self -> capacity) { uint32_t t_new_capacity; t_new_capacity = (self -> frontier + p_length + 255) & ~255; if (!MCMemoryReallocate(self -> buffer, t_new_capacity, self -> buffer)) return false; self -> capacity = t_new_capacity; } MCMemoryCopy((char *)self -> buffer + self -> frontier, p_data, p_length); self -> frontier += p_length; return true; } bool MCBinaryEncoderWriteInt32(MCBinaryEncoder *self, int32_t p_value) { return MCBinaryEncoderWriteUInt32(self, (uint32_t)p_value); } bool MCBinaryEncoderWriteUInt32(MCBinaryEncoder *self, uint32_t p_value) { uint32_t t_value; t_value = MCByteSwappedFromHost32(p_value); return MCBinaryEncoderWriteBytes(self, &t_value, sizeof(uint32_t)); } bool MCBinaryEncoderWriteCBlob(MCBinaryEncoder *self, const void *p_data, uint32_t p_length) { if (!MCBinaryEncoderWriteUInt32(self, p_length)) return false; return MCBinaryEncoderWriteBytes(self, p_data, p_length); } bool MCBinaryEncoderWriteCString(MCBinaryEncoder *self, const char *p_cstring) { uint32_t t_length; t_length = MCCStringLength(p_cstring); if (!MCBinaryEncoderWriteUInt32(self, t_length)) return false; return MCBinaryEncoderWriteBytes(self, p_cstring, t_length); } #ifdef _MACOSX bool MCBinaryEncoderWriteCFData(MCBinaryEncoder *self, CFDataRef cfdata) { return MCBinaryEncoderWriteCBlob(self, CFDataGetBytePtr(cfdata), CFDataGetLength(cfdata)); } bool MCBinaryEncoderWriteCFString(MCBinaryEncoder *self, CFStringRef p_cfstring) { CFDataRef t_data; t_data = CFStringCreateExternalRepresentation(kCFAllocatorDefault, p_cfstring, kCFStringEncodingUTF8, 0); if (t_data == nil) return false; bool t_success; t_success = MCBinaryEncoderWriteCFData(self, t_data); CFRelease(t_data); return t_success; } #endif //////////////////////////////////////////////////////////////////////////////// struct MCBinaryDecoder { uint32_t length; uint32_t frontier; const void *buffer; }; bool MCBinaryDecoderCreate(const void *p_buffer, uint32_t p_length, MCBinaryDecoder*& r_decoder) { MCBinaryDecoder *self; if (!MCMemoryNew(self)) return false; self -> length = p_length; self -> buffer = p_buffer; self -> frontier = 0; r_decoder = self; return true; } void MCBinaryDecoderDestroy(MCBinaryDecoder* self) { if (self == nil) return; MCMemoryDelete(self); } bool MCBinaryDecoderReadBytes(MCBinaryDecoder* self, void *p_buffer, uint32_t p_length) { if (self -> frontier + p_length > self -> length) return false; MCMemoryCopy(p_buffer, (char *)self -> buffer + self -> frontier, p_length); self -> frontier += p_length; return true; } bool MCBinaryDecoderReadUInt32(MCBinaryDecoder* self, uint32_t& r_value) { uint32_t t_value; if (!MCBinaryDecoderReadBytes(self, &t_value, 4)) return false; r_value = MCByteSwappedToHost32(t_value); return true; } bool MCBinaryDecoderReadInt32(MCBinaryDecoder* self, int32_t& r_value) { uint32_t t_value; if (!MCBinaryDecoderReadBytes(self, &t_value, 4)) return false; r_value = (int32_t)MCByteSwappedToHost32(t_value); return true; } bool MCBinaryDecoderReadCString(MCBinaryDecoder *self, char *&r_cstring) { uint32_t t_length; if (!MCBinaryDecoderReadUInt32(self, t_length)) return false; if (self -> frontier + t_length > self -> length) return false; char *t_string = nil; if (t_length > 0) { if (!MCCStringCloneSubstring((char*)self->buffer + self->frontier, t_length, t_string)) return false; self->frontier += t_length; } r_cstring = t_string; return true; } #ifdef _MACOSX bool MCBinaryDecoderReadCFString(MCBinaryDecoder* self, CFStringRef& r_cfstring) { uint32_t t_length; if (!MCBinaryDecoderReadUInt32(self, t_length)) return false; if (self -> frontier + t_length > self -> length) return false; CFDataRef t_data; t_data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (UInt8 *)self -> buffer + self -> frontier, t_length, kCFAllocatorNull); if (t_data == nil) return false; CFStringRef t_string; t_string = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, t_data, kCFStringEncodingUTF8); CFRelease(t_data); if (t_string != nil) { self -> frontier += t_length; r_cfstring = t_string; return true; } return false; } #endif ////////////////////////////////////////////////////////////////////////////////