diff --git a/cfecfs/eds2cfetbl/eds2cfetbl.c b/cfecfs/eds2cfetbl/eds2cfetbl.c index 83f8cbd..3fe7283 100644 --- a/cfecfs/eds2cfetbl/eds2cfetbl.c +++ b/cfecfs/eds2cfetbl/eds2cfetbl.c @@ -363,6 +363,8 @@ int Write_CFE_EnacapsulationFile(lua_State *lua) const char *OutputName = luaL_checkstring(lua, 1); EdsLib_DataTypeDB_TypeInfo_t BlockInfo; int lua_top; + const void *content_ptr; + size_t content_sz; lua_top = lua_gettop(lua); lua_getglobal(lua, "EdsDB"); @@ -378,6 +380,10 @@ int Write_CFE_EnacapsulationFile(lua_State *lua) printf("Generating file using EDS ID: %x\n", (unsigned int)PackedEdsId); PushEncodedBlob(lua); + if (lua_isnoneornil(lua, -1)) + { + return luaL_error(lua, "%s: Failed to encode object", OutputName); + } memset(&Buffer, 0, sizeof(Buffer)); Buffer.TblHeader.EdsAppId = EdsLib_Get_AppIdx(PackedEdsId); @@ -411,7 +417,16 @@ int Write_CFE_EnacapsulationFile(lua_State *lua) fwrite(PackedFileHeader, FileHeaderBlockSize, 1, OutputFile); fwrite(PackedTblHeader, TblHeaderBlockSize, 1, OutputFile); - fwrite(lua_tostring(lua, -1), lua_rawlen(lua, -1), 1, OutputFile); + content_ptr = lua_tostring(lua, -1); + content_sz = lua_rawlen(lua, -1); + if (content_ptr != NULL && content_sz > 0) + { + fwrite(content_ptr, content_sz, 1, OutputFile); + } + else + { + fprintf(stderr, "WARNING: No content produced\n"); + } fclose(OutputFile); printf("Wrote File: %s\n", OutputName); lua_pop(lua, 1); diff --git a/edslib/lua/src/edslib_lua_objects.c b/edslib/lua/src/edslib_lua_objects.c index 19f77fb..50a1b00 100644 --- a/edslib/lua/src/edslib_lua_objects.c +++ b/edslib/lua/src/edslib_lua_objects.c @@ -1,16 +1,16 @@ /* * LEW-19710-1, CCSDS SOIS Electronic Data Sheet Implementation - * + * * Copyright (c) 2020 United States Government as represented by * the Administrator of the National Aeronautics and Space Administration. * All Rights Reserved. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -734,7 +734,10 @@ static int EdsLib_LuaBinding_EncodeObject(lua_State *lua) EdsLib_DataTypeDB_TypeInfo_t PackedInfo; EdsLib_Id_t PackMsg; uint32_t MaxByteSize; - luaL_Buffer PackBuf; + uint8_t LocalScratchBuffer[64]; + void *PackBufPtr; + int32_t PackStatus; + int nret; ObjectUserData = luaL_checkudata(lua, 1, "EdsLib_Object"); @@ -750,20 +753,48 @@ static int EdsLib_LuaBinding_EncodeObject(lua_State *lua) MaxByteSize = ObjectUserData->TypeInfo.Size.Bytes; } + nret = 0; PackMsg = ObjectUserData->EdsId; - luaL_buffinit(lua, &PackBuf); - EdsLib_DataTypeDB_PackCompleteObject(ObjectUserData->GD, - &PackMsg, - luaL_prepbuffer(&PackBuf), - EdsLib_Binding_GetNativeObject(ObjectUserData), - 8 * LUAL_BUFFERSIZE, - MaxByteSize); - - EdsLib_DataTypeDB_GetTypeInfo(ObjectUserData->GD, PackMsg, &PackedInfo); - luaL_addsize(&PackBuf, (PackedInfo.Size.Bits + 7) / 8); - luaL_pushresult(&PackBuf); - return 1; + /* + * Use the local stack scratch buffer for smaller objects, or + * Use the heap/malloc for larger objects + */ + if (MaxByteSize <= sizeof(LocalScratchBuffer)) + { + PackBufPtr = LocalScratchBuffer; + } + else + { + PackBufPtr = malloc(MaxByteSize); + } + + if (PackBufPtr != NULL) + { + memset(PackBufPtr, 0, MaxByteSize); + + PackStatus = EdsLib_DataTypeDB_PackCompleteObject(ObjectUserData->GD, + &PackMsg, + PackBufPtr, + EdsLib_Binding_GetNativeObject(ObjectUserData), + 8 * MaxByteSize, + MaxByteSize); + + if (PackStatus == EDSLIB_SUCCESS) + { + EdsLib_DataTypeDB_GetTypeInfo(ObjectUserData->GD, PackMsg, &PackedInfo); + lua_pushlstring(lua, PackBufPtr, (PackedInfo.Size.Bits + 7) / 8); + ++nret; + } + + /* Free the buffer if it was from heap */ + if (PackBufPtr != LocalScratchBuffer) + { + free(PackBufPtr); + } + } + + return nret; } static int EdsLib_LuaBinding_GetMetaData(lua_State *lua)