Exemple #1
0
IO_stat MCCdata::load(IO_handle stream, MCObject *parent, const char *version)
{
	IO_stat stat;

	if ((stat = IO_read_uint4(&id, stream)) != IO_NORMAL)
		return stat;
	if (parent->gettype() == CT_BUTTON)
	{
		uint1 set;
		stat = IO_read_uint1(&set, stream);
		data = (void *)(set ? 1 : 0);
		return stat;
	}
	else
	{
		if (id & COMPACT_PARAGRAPHS)
		{
			char *string;
			if ((stat = IO_read_string(string, stream, sizeof(uint1))) != IO_NORMAL)
				return stat;
			data = string;
		}
		else
		{
			MCParagraph *paragraphs = NULL;
			while (True)
			{
				uint1 type;
				if ((stat = IO_read_uint1(&type, stream)) != IO_NORMAL)
					return stat;
				switch (type)
				{
				// MW-2012-03-04: [[ StackFile5500 ]] Handle either the paragraph or extended
				//   paragraph tag.
				case OT_PARAGRAPH:
				case OT_PARAGRAPH_EXT:
					{
						MCParagraph *newpar = new MCParagraph;
						newpar->setparent((MCField *)parent);
						
						// MW-2012-03-04: [[ StackFile5500 ]] If the paragraph tab was the extended
						//   variant, then pass the correct is_ext parameter.
						if ((stat = newpar->load(stream, version, type == OT_PARAGRAPH_EXT)) != IO_NORMAL)
						{
							delete newpar;
							return stat;
						}
						newpar->appendto(paragraphs);
					}
					break;
				default:
					data = paragraphs;
					MCS_seek_cur(stream, -1);
					return IO_NORMAL;
				}
			}
		}
	}
	return IO_NORMAL;
}
Exemple #2
0
IO_stat MCStyledText::load(IO_handle p_stream, const char *p_version)
{
	IO_stat stat;
	MCParagraph *paragraphs = NULL;
	while (True)
	{
		uint1 type;
		if ((stat = IO_read_uint1(&type, p_stream)) != IO_NORMAL)
			return stat;
		switch (type)
		{
		// MW-2012-03-04: [[ StackFile5500 ]] Handle both the paragraph and extended
		//   paragraph record.
		case OT_PARAGRAPH:
		case OT_PARAGRAPH_EXT:
			{
				MCParagraph *newpar = new MCParagraph;
				newpar->setparent((MCField *)parent);
				
				// MW-2012-03-04: [[ StackFile5500 ]] If the record is extended then
				//   pass in 'true' for 'is_ext'.
				if ((stat = newpar->load(p_stream, p_version, type == OT_PARAGRAPH_EXT)) != IO_NORMAL)
				{
					delete newpar;
					return stat;
				}

				newpar->appendto(paragraphs);
			}
			break;
		default:
			m_paragraphs = paragraphs;
			MCS_seek_cur(p_stream, -1);
			return IO_NORMAL;
		}
	}
	return IO_NORMAL;
}
Exemple #3
0
IO_stat IO_read_string(char *&r_string, uint32_t &r_length, IO_handle p_stream, uint8_t p_size, bool p_includes_null, bool p_translate)
{
	IO_stat stat;
	
	uint32_t t_length = 0;
	uint32_t t_bytes = 0;
	
	switch (p_size)
	{
		case 1:
		{
			uint8_t t_len;
			if ((stat = IO_read_uint1(&t_len, p_stream)) != IO_NORMAL)
				return stat;
			t_bytes = t_len;
			break;
		}
		case 2:
		{
			uint16_t t_len;
			if ((stat = IO_read_uint2(&t_len, p_stream)) != IO_NORMAL)
				return stat;
			t_bytes = t_len;
			break;
		}
		case 4:
		{
			uint32_t t_len;
			if ((stat = IO_read_uint4(&t_len, p_stream)) != IO_NORMAL)
				return stat;
			t_bytes = t_len;
			break;
		}
	}
	
	char *t_string = nil;
	if (t_bytes != 0)
	{
		t_length = p_includes_null ? t_bytes - 1 : t_bytes;
		/* UNCHECKED */ t_string = new char[t_bytes];
		stat = MCStackSecurityRead(t_string, t_length, p_stream);
		if (stat == IO_NORMAL && p_includes_null)
			stat = IO_read_uint1((uint1*)t_string + t_length, p_stream);
		if (stat != IO_NORMAL)
		{
			delete t_string;
			return stat;
		}

		if (MCtranslatechars && p_translate)
		{
#ifdef __MACROMAN__
			IO_iso_to_mac(t_string, t_length);
#else
			IO_mac_to_iso(t_string, t_length);
#endif
			
		}
	}
	
	r_string = t_string;
	r_length = t_length;
	
	return IO_NORMAL;
}
Exemple #4
0
void MCArraysEvalArrayDecode(MCExecContext& ctxt, MCDataRef p_encoding, MCArrayRef& r_array)
{
	bool t_success;
	t_success = true;

	IO_handle t_stream_handle;
	t_stream_handle = nil;
    if (t_success)
    {
        t_stream_handle = MCS_fakeopen(MCDataGetBytePtr(p_encoding), MCDataGetLength(p_encoding));
		if (t_stream_handle == nil)
			t_success = false;
	}

    uint8_t t_type;
	if (t_success)
		if (IO_read_uint1(&t_type, t_stream_handle) != IO_NORMAL)
			t_success = false;
        
    // AL-2014-05-01: [[ Bug 11989 ]] If the type is 'empty' then just return the empty array.
	if (t_success && t_type == kMCEncodedValueTypeEmpty)
    {
        r_array = MCValueRetain(kMCEmptyArray);
        return;
    }
    
    // AL-2014-05-15: [[ Bug 12203 ]] Check initial byte for version 7.0 encoded array.
    bool t_legacy;
    t_legacy = t_type < kMCEncodedValueTypeArray;
    
    MCArrayRef t_array;
	t_array = nil;
	if (t_success)
		t_success = MCArrayCreateMutable(t_array);

	if (t_legacy)
    {
        if (t_success)
            if (MCS_putback(t_type, t_stream_handle) != IO_NORMAL)
                t_success = false;
        
        MCObjectInputStream *t_stream;
        t_stream = nil;
        if (t_success)
        {
            t_stream = new MCObjectInputStream(t_stream_handle, MCDataGetLength(p_encoding), false);
            if (t_stream == nil)
                t_success = false;
        }
        
        if (t_success)
            if (t_stream -> ReadU8(t_type) != IO_NORMAL)
                t_success = false;
        
        if (t_success)
            if (MCArrayLoadFromStreamLegacy(t_array, *t_stream) != IO_NORMAL)
                t_success = false;
        
        delete t_stream;
    }
    else
    {
        if (t_success)
            if (IO_read_valueref_new((MCValueRef &)t_array, t_stream_handle) != IO_NORMAL)
                t_success = false;
    }
    
	MCS_close(t_stream_handle);

	if (t_success)
	{
		r_array = t_array;
		return;
	}

	MCValueRelease(t_array);

	ctxt . Throw();
}
Exemple #5
0
// MW-2012-02-17: [[ LogFonts ]] Actually load the stack file (wrapped by readfile
//   to handle font table cleanup).
IO_stat MCDispatch::doreadfile(const char *openpath, const char *inname, IO_handle &stream, MCStack *&sptr)
{
	Boolean loadhome = False;
	char version[8];

	if (readheader(stream, version) == IO_NORMAL)
	{
		if (strcmp(version, MCversionstring) > 0)
		{
			MCresult->sets("stack was produced by a newer version");
			return IO_ERROR;
		}

		// MW-2008-10-20: [[ ParentScripts ]] Set the boolean flag that tells us whether
		//   parentscript resolution is required to false.
		s_loaded_parent_script_reference = false;

		uint1 charset, type;
		char *newsf;
		if (IO_read_uint1(&charset, stream) != IO_NORMAL
		        || IO_read_uint1(&type, stream) != IO_NORMAL
		        || IO_read_string(newsf, stream) != IO_NORMAL)
		{
			MCresult->sets("stack is corrupted, check for ~ backup file");
			return IO_ERROR;
		}
		delete newsf; // stackfiles is obsolete
		MCtranslatechars = charset != CHARSET;
		sptr = nil;
		/* UNCHECKED */ MCStackSecurityCreateStack(sptr);
		if (stacks == NULL)
			sptr->setparent(this);
		else
			sptr->setparent(stacks);
		sptr->setfilename(strclone(openpath));

		if (MCModeCanLoadHome() && type == OT_HOME)
		{
			char *lstring = NULL;
			char *cstring = NULL;
			IO_read_string(lstring, stream);
			IO_read_string(cstring, stream);
			delete lstring;
			delete cstring;
		}

		MCresult -> clear();

		if (IO_read_uint1(&type, stream) != IO_NORMAL
		    || type != OT_STACK && type != OT_ENCRYPT_STACK
		    || sptr->load(stream, version, type) != IO_NORMAL)
		{
			if (MCresult -> isclear())
				MCresult->sets("stack is corrupted, check for ~ backup file");
			destroystack(sptr, False);
			sptr = NULL;
			return IO_ERROR;
		}
		
		// MW-2011-08-09: [[ Groups ]] Make sure F_GROUP_SHARED is set
		//   appropriately.
		sptr -> checksharedgroups();
		
		if (sptr->load_substacks(stream, version) != IO_NORMAL
		        || IO_read_uint1(&type, stream) != IO_NORMAL
		        || type != OT_END)
		{
			if (MCresult -> isclear())
				MCresult->sets("stack is corrupted, check for ~ backup file");
			destroystack(sptr, False);
			sptr = NULL;
			return IO_ERROR;
		}

		if (stacks != NULL)
		{
			MCStack *tstk = stacks;
			do
			{
				if (sptr->hasname(tstk->getname()))
				{
					MCAutoNameRef t_stack_name;
					/* UNCHECKED */ t_stack_name . Clone(sptr -> getname());

					delete sptr;
					sptr = NULL;

					if (strequal(tstk->getfilename(), openpath))
						sptr = tstk;
					else
					{
						MCdefaultstackptr->getcard()->message_with_args(MCM_reload_stack, MCNameGetOldString(tstk->getname()), openpath);
						tstk = stacks;
						do
						{
							if (MCNameIsEqualTo(t_stack_name, tstk->getname(), kMCCompareCaseless))
							{
								sptr = tstk;
								break;
							}
							tstk = (MCStack *)tstk->next();
						}
						while (tstk != stacks);
					}

					return IO_NORMAL;
				}
				tstk = (MCStack *)tstk->next();
			}
			while (tstk != stacks);
		}
		
		appendstack(sptr);
		
		sptr->extraopen(false);

		// MW-2008-10-28: [[ ParentScript ]]
		// We just loaded a stackfile, so check to see if parentScript resolution
		// is required and if so do it.
		// MW-2009-01-28: [[ Inherited parentScripts ]]
		// Resolving parentScripts may allocate memory, so 'resolveparentscripts'
		// will return false if it fails to allocate what it needs. At some point
		// this needs to be dealt with by deleting the stack and returning an error,
		// *However* at the time of writing, 'readfile' isn't designed to handle
		// this - so we just ignore the result for now (note that all the 'load'
		// methods *fail* to check for no-memory errors!).
		if (s_loaded_parent_script_reference)
			sptr -> resolveparentscripts();
		
	}
	else
	{
		MCS_seek_set(stream, 0);
		if (stacks == NULL)
		{
			MCnoui = True;
			MCscreen = new MCUIDC;
			/* UNCHECKED */ MCStackSecurityCreateStack(stacks);
			MCdefaultstackptr = MCstaticdefaultstackptr = stacks;
			stacks->setparent(this);
			stacks->setname_cstring("revScript");
			uint4 size = (uint4)MCS_fsize(stream);
			char *script = new char[size + 2];
			script[size] = '\n';
			script[size + 1] = '\0';
			if (IO_read(script, sizeof(char), size, stream) != IO_NORMAL
			        || !stacks->setscript(script))
			{
				delete script;
				return IO_ERROR;
			}
		}
		else
		{
			char *tname = strclone(inname);
			
			// MW-2008-06-12: [[ Bug 6476 ]] Media won't open HC stacks
			if (!MCdispatcher->cut(True) || hc_import(tname, stream, sptr) != IO_NORMAL)
			{
				MCresult->sets("file is not a stack");
				delete tname;
				return IO_ERROR;
			}
		}
	}
	return IO_NORMAL;
}
Exemple #6
0
// This method reads a stack from the given stream. The stack is set to
// have parent MCDispatch, and filename MCcmd. It is designed to be used
// for embedded stacks/deployed stacks/revlet stacks.
IO_stat MCDispatch::readstartupstack(IO_handle stream, MCStack*& r_stack)
{
	char version[8];
	uint1 charset, type;
	char *newsf;
	if (readheader(stream, version) != IO_NORMAL
	        || IO_read_uint1(&charset, stream) != IO_NORMAL
	        || IO_read_uint1(&type, stream) != IO_NORMAL
	        || IO_read_string(newsf, stream) != IO_NORMAL)
		return IO_ERROR;

	// MW-2008-10-20: [[ ParentScripts ]] Set the boolean flag that tells us whether
	//   parentscript resolution is required to false.
	s_loaded_parent_script_reference = false;

	MCtranslatechars = charset != CHARSET;
	delete newsf; // stackfiles is obsolete

	MCStack *t_stack = nil;
	/* UNCHECKED */ MCStackSecurityCreateStack(t_stack);
	t_stack -> setparent(this);
	
	// MM-2013-10-30: [[ Bug 11333 ]] Set the filename of android mainstack to apk/mainstack (previously was just apk).
	//   This solves relative file path referencing issues.
#ifdef TARGET_SUBPLATFORM_ANDROID
    char *t_filename;
    /* UNCHECKED */ MCMemoryNewArray(MCCStringLength(MCcmd) + 11, t_filename);
    MCCStringFormat(t_filename, "%s/mainstack", MCcmd);
	t_stack -> setfilename(t_filename);
#else
   	t_stack -> setfilename(strclone(MCcmd));
#endif
	
	
	if (IO_read_uint1(&type, stream) != IO_NORMAL
	        || type != OT_STACK && type != OT_ENCRYPT_STACK
	        || t_stack->load(stream, version, type) != IO_NORMAL)
	{
		delete t_stack;
		return IO_ERROR;
	}

	if (t_stack->load_substacks(stream, version) != IO_NORMAL
	        || IO_read_uint1(&type, stream) != IO_NORMAL
	        || type != OT_END)
	{
		delete t_stack;
		return IO_ERROR;
	}

	// We are reading the startup stack, so this becomes the root of the
	// stack list.
	stacks = t_stack;

	r_stack = t_stack;

#ifndef _MOBILE
	// Make sure parent script references are up to date.
	if (s_loaded_parent_script_reference)
		t_stack -> resolveparentscripts();
#else
	// Mark the stack as needed parentscript resolution. This is done after
	// aux stacks have been loaded.
	if (s_loaded_parent_script_reference)
		t_stack -> setextendedstate(True, ECS_USES_PARENTSCRIPTS);
#endif

	return IO_NORMAL;
}
Exemple #7
0
IO_stat MCCdata::load(IO_handle stream, MCObject *parent, uint32_t version)
{
	IO_stat stat;

	if ((stat = IO_read_uint4(&id, stream)) != IO_NORMAL)
		return checkloadstat(stat);
	if (parent->gettype() == CT_BUTTON)
	{
		uint1 set;
		stat = IO_read_uint1(&set, stream);
		data = reinterpret_cast<void *>(set ? 1 : 0);
		return checkloadstat(stat);
	}
	else
	{
		if (id & COMPACT_PARAGRAPHS)
		{
			// MW-2013-11-19: [[ UnicodeFileFormat ]] This flag is never set by newer engines
			//   so is just legacy.
			char *string;
			if ((stat = IO_read_cstring_legacy(string, stream, sizeof(uint1))) != IO_NORMAL)
				return checkloadstat(stat);
			data = string;
		}
		else
		{
			MCParagraph *paragraphs = NULL;
			while (True)
			{
				uint1 type;
				if ((stat = IO_read_uint1(&type, stream)) != IO_NORMAL)
					return checkloadstat(stat);
				switch (type)
				{
				// MW-2012-03-04: [[ StackFile5500 ]] Handle either the paragraph or extended
				//   paragraph tag.
				case OT_PARAGRAPH:
				case OT_PARAGRAPH_EXT:
					{
						MCParagraph *newpar = new (nothrow) MCParagraph;
						newpar->setparent((MCField *)parent);
						
						// MW-2012-03-04: [[ StackFile5500 ]] If the paragraph tab was the extended
						//   variant, then pass the correct is_ext parameter.
						if ((stat = newpar->load(stream, version, type == OT_PARAGRAPH_EXT)) != IO_NORMAL)
						{
							delete newpar;
							return checkloadstat(stat);
						}
						newpar->appendto(paragraphs);
					}
					break;
				default:
					data = paragraphs;
					MCS_seek_cur(stream, -1);
					return IO_NORMAL;
				}
			}
		}
	}
	return IO_NORMAL;
}
Exemple #8
0
IO_stat MCParagraph::load(IO_handle stream, const char *version)
{
	IO_stat stat;
	stat = IO_NORMAL;

	if (stat == IO_NORMAL)
		stat = IO_read_uint2(&m_text_size, stream);

	if (m_text_size == 1)
	{
		if (stat == IO_NORMAL)
		{
			char t_temp;
			uint4 t_temp_count;
			t_temp_count = 1;
			stat = IO_read(&t_temp, sizeof(uint1), t_temp_count, stream);
		}

		if (stat == IO_NORMAL)
			m_text_size = 0;
	}
	else if (m_text_size > 1)
	{
		if (stat == IO_NORMAL)
		{
			m_text = malloc(m_text_size);
			if (m_text == NULL)
				stat = IO_ERROR;
		}

		if (stat == IO_NORMAL)
		{
			uint4 t_temp_text_size;
			t_temp_text_size = m_text_size;
			stat = IO_read(m_text, sizeof(uint1), t_temp_text_size, stream);
		}

		if (stat == IO_NORMAL)
		{
			if (MCencryptstring != NULL)
				MCX_passde((char *)m_text, MCencryptstring, m_text_size);

			m_text_size -= 1;
		}
	}

	while(stat == IO_NORMAL)
	{
		uint1 t_type;
		stat = IO_read_uint1(&t_type, stream);
		if (stat != IO_NORMAL)
			break;

		uint4 t_block_offset, t_block_length, t_block_style;
		stat = load_block(stream, version, t_block_offset, t_block_length, t_block_style);
		if (stat != IO_NORMAL)
			break;

		// Make sure the block doesn't overrun the text buffer (shouldn't ever be
		// necessary...)
		t_block_length = MCU_min(m_text_size - t_block_offset, t_block_length);

		// Byte-swap the text to native byte-order if its unicode, otherwise translate
		// Mac<->ISO if necessary.
		const MCParagraphCharStyle *t_style_info;
		t_style_info = FetchCharStyle(t_block_style);
		if (t_style_info -> is_unicode)
		{
			uint4 t_length;
			t_length = t_block_length / 2;

			uint2 *t_ptr;
			t_ptr = (uint2 *)((uint1 *)m_text + t_block_offset);

			for(; t_length > 0; t_length -= 1)
				swap_uint2(t_ptr++);
		}
		else if (MCtranslatechars)
		{
#ifdef _MACOSX
			IO_iso_to_mac((char *)m_text + t_block_offset, t_block_length);
#else
			IO_mac_to_iso((char *)m_text + t_block_offset, t_block_length);
#endif
		}

		// Replace the style in the given range with the style
		ReplaceStyles(t_block_offset, t_block_length, t_block_style);
	}

	if (stat == IO_NORMAL)
	{
		// If no styles were applied, we need to translate the text
		if (m_styles_size == 0 && MCtranslatechars && m_text_size > 0)
#ifdef _MACOSX
			IO_iso_to_mac((char *)m_text, m_text_size);
#else
			IO_mac_to_iso((char *)m_text, m_text_size);
#endif

		Compact();

		MCS_seek_cur(stream, -1);
	}

	return stat;
}